Merge branch 'for-greg' of git://gitorious.org/usb/usb into usb-linus
[pandora-kernel.git] / drivers / media / video / vpx3220.c
1 /*
2  * vpx3220a, vpx3216b & vpx3214c video decoder driver version 0.0.1
3  *
4  * Copyright (C) 2001 Laurent Pinchart <lpinchart@freegates.be>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 #include <linux/module.h>
22 #include <linux/init.h>
23 #include <linux/delay.h>
24 #include <linux/types.h>
25 #include <linux/slab.h>
26 #include <asm/uaccess.h>
27 #include <linux/i2c.h>
28 #include <linux/videodev2.h>
29 #include <media/v4l2-device.h>
30 #include <media/v4l2-chip-ident.h>
31 #include <media/v4l2-ctrls.h>
32
33 MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
34 MODULE_AUTHOR("Laurent Pinchart");
35 MODULE_LICENSE("GPL");
36
37 static int debug;
38 module_param(debug, int, 0);
39 MODULE_PARM_DESC(debug, "Debug level (0-1)");
40
41
42 #define VPX_TIMEOUT_COUNT  10
43
44 /* ----------------------------------------------------------------------- */
45
46 struct vpx3220 {
47         struct v4l2_subdev sd;
48         struct v4l2_ctrl_handler hdl;
49         unsigned char reg[255];
50
51         v4l2_std_id norm;
52         int ident;
53         int input;
54         int enable;
55 };
56
57 static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev *sd)
58 {
59         return container_of(sd, struct vpx3220, sd);
60 }
61
62 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
63 {
64         return &container_of(ctrl->handler, struct vpx3220, hdl)->sd;
65 }
66
67 static char *inputs[] = { "internal", "composite", "svideo" };
68
69 /* ----------------------------------------------------------------------- */
70
71 static inline int vpx3220_write(struct v4l2_subdev *sd, u8 reg, u8 value)
72 {
73         struct i2c_client *client = v4l2_get_subdevdata(sd);
74         struct vpx3220 *decoder = i2c_get_clientdata(client);
75
76         decoder->reg[reg] = value;
77         return i2c_smbus_write_byte_data(client, reg, value);
78 }
79
80 static inline int vpx3220_read(struct v4l2_subdev *sd, u8 reg)
81 {
82         struct i2c_client *client = v4l2_get_subdevdata(sd);
83
84         return i2c_smbus_read_byte_data(client, reg);
85 }
86
87 static int vpx3220_fp_status(struct v4l2_subdev *sd)
88 {
89         unsigned char status;
90         unsigned int i;
91
92         for (i = 0; i < VPX_TIMEOUT_COUNT; i++) {
93                 status = vpx3220_read(sd, 0x29);
94
95                 if (!(status & 4))
96                         return 0;
97
98                 udelay(10);
99
100                 if (need_resched())
101                         cond_resched();
102         }
103
104         return -1;
105 }
106
107 static int vpx3220_fp_write(struct v4l2_subdev *sd, u8 fpaddr, u16 data)
108 {
109         struct i2c_client *client = v4l2_get_subdevdata(sd);
110
111         /* Write the 16-bit address to the FPWR register */
112         if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) {
113                 v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
114                 return -1;
115         }
116
117         if (vpx3220_fp_status(sd) < 0)
118                 return -1;
119
120         /* Write the 16-bit data to the FPDAT register */
121         if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) {
122                 v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
123                 return -1;
124         }
125
126         return 0;
127 }
128
129 static u16 vpx3220_fp_read(struct v4l2_subdev *sd, u16 fpaddr)
130 {
131         struct i2c_client *client = v4l2_get_subdevdata(sd);
132         s16 data;
133
134         /* Write the 16-bit address to the FPRD register */
135         if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) {
136                 v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
137                 return -1;
138         }
139
140         if (vpx3220_fp_status(sd) < 0)
141                 return -1;
142
143         /* Read the 16-bit data from the FPDAT register */
144         data = i2c_smbus_read_word_data(client, 0x28);
145         if (data == -1) {
146                 v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
147                 return -1;
148         }
149
150         return swab16(data);
151 }
152
153 static int vpx3220_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
154 {
155         u8 reg;
156         int ret = -1;
157
158         while (len >= 2) {
159                 reg = *data++;
160                 ret = vpx3220_write(sd, reg, *data++);
161                 if (ret < 0)
162                         break;
163                 len -= 2;
164         }
165
166         return ret;
167 }
168
169 static int vpx3220_write_fp_block(struct v4l2_subdev *sd,
170                 const u16 *data, unsigned int len)
171 {
172         u8 reg;
173         int ret = 0;
174
175         while (len > 1) {
176                 reg = *data++;
177                 ret |= vpx3220_fp_write(sd, reg, *data++);
178                 len -= 2;
179         }
180
181         return ret;
182 }
183
184 /* ---------------------------------------------------------------------- */
185
186 static const unsigned short init_ntsc[] = {
187         0x1c, 0x00,             /* NTSC tint angle */
188         0x88, 17,               /* Window 1 vertical */
189         0x89, 240,              /* Vertical lines in */
190         0x8a, 240,              /* Vertical lines out */
191         0x8b, 000,              /* Horizontal begin */
192         0x8c, 640,              /* Horizontal length */
193         0x8d, 640,              /* Number of pixels */
194         0x8f, 0xc00,            /* Disable window 2 */
195         0xf0, 0x73,             /* 13.5 MHz transport, Forced
196                                  * mode, latch windows */
197         0xf2, 0x13,             /* NTSC M, composite input */
198         0xe7, 0x1e1,            /* Enable vertical standard
199                                  * locking @ 240 lines */
200 };
201
202 static const unsigned short init_pal[] = {
203         0x88, 23,               /* Window 1 vertical begin */
204         0x89, 288,              /* Vertical lines in (16 lines
205                                  * skipped by the VFE) */
206         0x8a, 288,              /* Vertical lines out (16 lines
207                                  * skipped by the VFE) */
208         0x8b, 16,               /* Horizontal begin */
209         0x8c, 768,              /* Horizontal length */
210         0x8d, 784,              /* Number of pixels
211                                  * Must be >= Horizontal begin + Horizontal length */
212         0x8f, 0xc00,            /* Disable window 2 */
213         0xf0, 0x77,             /* 13.5 MHz transport, Forced
214                                  * mode, latch windows */
215         0xf2, 0x3d1,            /* PAL B,G,H,I, composite input */
216         0xe7, 0x241,            /* PAL/SECAM set to 288 lines */
217 };
218
219 static const unsigned short init_secam[] = {
220         0x88, 23,               /* Window 1 vertical begin */
221         0x89, 288,              /* Vertical lines in (16 lines
222                                  * skipped by the VFE) */
223         0x8a, 288,              /* Vertical lines out (16 lines
224                                  * skipped by the VFE) */
225         0x8b, 16,               /* Horizontal begin */
226         0x8c, 768,              /* Horizontal length */
227         0x8d, 784,              /* Number of pixels
228                                  * Must be >= Horizontal begin + Horizontal length */
229         0x8f, 0xc00,            /* Disable window 2 */
230         0xf0, 0x77,             /* 13.5 MHz transport, Forced
231                                  * mode, latch windows */
232         0xf2, 0x3d5,            /* SECAM, composite input */
233         0xe7, 0x241,            /* PAL/SECAM set to 288 lines */
234 };
235
236 static const unsigned char init_common[] = {
237         0xf2, 0x00,             /* Disable all outputs */
238         0x33, 0x0d,             /* Luma : VIN2, Chroma : CIN
239                                  * (clamp off) */
240         0xd8, 0xa8,             /* HREF/VREF active high, VREF
241                                  * pulse = 2, Odd/Even flag */
242         0x20, 0x03,             /* IF compensation 0dB/oct */
243         0xe0, 0xff,             /* Open up all comparators */
244         0xe1, 0x00,
245         0xe2, 0x7f,
246         0xe3, 0x80,
247         0xe4, 0x7f,
248         0xe5, 0x80,
249         0xe6, 0x00,             /* Brightness set to 0 */
250         0xe7, 0xe0,             /* Contrast to 1.0, noise shaping
251                                  * 10 to 8 2-bit error diffusion */
252         0xe8, 0xf8,             /* YUV422, CbCr binary offset,
253                                  * ... (p.32) */
254         0xea, 0x18,             /* LLC2 connected, output FIFO
255                                  * reset with VACTintern */
256         0xf0, 0x8a,             /* Half full level to 10, bus
257                                  * shuffler [7:0, 23:16, 15:8] */
258         0xf1, 0x18,             /* Single clock, sync mode, no
259                                  * FE delay, no HLEN counter */
260         0xf8, 0x12,             /* Port A, PIXCLK, HF# & FE#
261                                  * strength to 2 */
262         0xf9, 0x24,             /* Port B, HREF, VREF, PREF &
263                                  * ALPHA strength to 4 */
264 };
265
266 static const unsigned short init_fp[] = {
267         0x59, 0,
268         0xa0, 2070,             /* ACC reference */
269         0xa3, 0,
270         0xa4, 0,
271         0xa8, 30,
272         0xb2, 768,
273         0xbe, 27,
274         0x58, 0,
275         0x26, 0,
276         0x4b, 0x298,            /* PLL gain */
277 };
278
279
280 static int vpx3220_init(struct v4l2_subdev *sd, u32 val)
281 {
282         struct vpx3220 *decoder = to_vpx3220(sd);
283
284         vpx3220_write_block(sd, init_common, sizeof(init_common));
285         vpx3220_write_fp_block(sd, init_fp, sizeof(init_fp) >> 1);
286         if (decoder->norm & V4L2_STD_NTSC)
287                 vpx3220_write_fp_block(sd, init_ntsc, sizeof(init_ntsc) >> 1);
288         else if (decoder->norm & V4L2_STD_PAL)
289                 vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
290         else if (decoder->norm & V4L2_STD_SECAM)
291                 vpx3220_write_fp_block(sd, init_secam, sizeof(init_secam) >> 1);
292         else
293                 vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
294         return 0;
295 }
296
297 static int vpx3220_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
298 {
299         int res = V4L2_IN_ST_NO_SIGNAL, status;
300         v4l2_std_id std = 0;
301
302         status = vpx3220_fp_read(sd, 0x0f3);
303
304         v4l2_dbg(1, debug, sd, "status: 0x%04x\n", status);
305
306         if (status < 0)
307                 return status;
308
309         if ((status & 0x20) == 0) {
310                 res = 0;
311
312                 switch (status & 0x18) {
313                 case 0x00:
314                 case 0x10:
315                 case 0x14:
316                 case 0x18:
317                         std = V4L2_STD_PAL;
318                         break;
319
320                 case 0x08:
321                         std = V4L2_STD_SECAM;
322                         break;
323
324                 case 0x04:
325                 case 0x0c:
326                 case 0x1c:
327                         std = V4L2_STD_NTSC;
328                         break;
329                 }
330         }
331         if (pstd)
332                 *pstd = std;
333         if (pstatus)
334                 *pstatus = status;
335         return 0;
336 }
337
338 static int vpx3220_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
339 {
340         v4l2_dbg(1, debug, sd, "querystd\n");
341         return vpx3220_status(sd, NULL, std);
342 }
343
344 static int vpx3220_g_input_status(struct v4l2_subdev *sd, u32 *status)
345 {
346         v4l2_dbg(1, debug, sd, "g_input_status\n");
347         return vpx3220_status(sd, status, NULL);
348 }
349
350 static int vpx3220_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
351 {
352         struct vpx3220 *decoder = to_vpx3220(sd);
353         int temp_input;
354
355         /* Here we back up the input selection because it gets
356            overwritten when we fill the registers with the
357            chosen video norm */
358         temp_input = vpx3220_fp_read(sd, 0xf2);
359
360         v4l2_dbg(1, debug, sd, "s_std %llx\n", (unsigned long long)std);
361         if (std & V4L2_STD_NTSC) {
362                 vpx3220_write_fp_block(sd, init_ntsc, sizeof(init_ntsc) >> 1);
363                 v4l2_dbg(1, debug, sd, "norm switched to NTSC\n");
364         } else if (std & V4L2_STD_PAL) {
365                 vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
366                 v4l2_dbg(1, debug, sd, "norm switched to PAL\n");
367         } else if (std & V4L2_STD_SECAM) {
368                 vpx3220_write_fp_block(sd, init_secam, sizeof(init_secam) >> 1);
369                 v4l2_dbg(1, debug, sd, "norm switched to SECAM\n");
370         } else {
371                 return -EINVAL;
372         }
373
374         decoder->norm = std;
375
376         /* And here we set the backed up video input again */
377         vpx3220_fp_write(sd, 0xf2, temp_input | 0x0010);
378         udelay(10);
379         return 0;
380 }
381
382 static int vpx3220_s_routing(struct v4l2_subdev *sd,
383                              u32 input, u32 output, u32 config)
384 {
385         int data;
386
387         /* RJ:   input = 0: ST8 (PCTV) input
388                  input = 1: COMPOSITE  input
389                  input = 2: SVHS       input  */
390
391         const int input_vals[3][2] = {
392                 {0x0c, 0},
393                 {0x0d, 0},
394                 {0x0e, 1}
395         };
396
397         if (input > 2)
398                 return -EINVAL;
399
400         v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[input]);
401
402         vpx3220_write(sd, 0x33, input_vals[input][0]);
403
404         data = vpx3220_fp_read(sd, 0xf2) & ~(0x0020);
405         if (data < 0)
406                 return data;
407         /* 0x0010 is required to latch the setting */
408         vpx3220_fp_write(sd, 0xf2,
409                         data | (input_vals[input][1] << 5) | 0x0010);
410
411         udelay(10);
412         return 0;
413 }
414
415 static int vpx3220_s_stream(struct v4l2_subdev *sd, int enable)
416 {
417         v4l2_dbg(1, debug, sd, "s_stream %s\n", enable ? "on" : "off");
418
419         vpx3220_write(sd, 0xf2, (enable ? 0x1b : 0x00));
420         return 0;
421 }
422
423 static int vpx3220_s_ctrl(struct v4l2_ctrl *ctrl)
424 {
425         struct v4l2_subdev *sd = to_sd(ctrl);
426
427         switch (ctrl->id) {
428         case V4L2_CID_BRIGHTNESS:
429                 vpx3220_write(sd, 0xe6, ctrl->val);
430                 return 0;
431         case V4L2_CID_CONTRAST:
432                 /* Bit 7 and 8 is for noise shaping */
433                 vpx3220_write(sd, 0xe7, ctrl->val + 192);
434                 return 0;
435         case V4L2_CID_SATURATION:
436                 vpx3220_fp_write(sd, 0xa0, ctrl->val);
437                 return 0;
438         case V4L2_CID_HUE:
439                 vpx3220_fp_write(sd, 0x1c, ctrl->val);
440                 return 0;
441         }
442         return -EINVAL;
443 }
444
445 static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
446 {
447         struct vpx3220 *decoder = to_vpx3220(sd);
448         struct i2c_client *client = v4l2_get_subdevdata(sd);
449
450         return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
451 }
452
453 /* ----------------------------------------------------------------------- */
454
455 static const struct v4l2_ctrl_ops vpx3220_ctrl_ops = {
456         .s_ctrl = vpx3220_s_ctrl,
457 };
458
459 static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
460         .g_chip_ident = vpx3220_g_chip_ident,
461         .init = vpx3220_init,
462         .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
463         .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
464         .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
465         .g_ctrl = v4l2_subdev_g_ctrl,
466         .s_ctrl = v4l2_subdev_s_ctrl,
467         .queryctrl = v4l2_subdev_queryctrl,
468         .querymenu = v4l2_subdev_querymenu,
469         .s_std = vpx3220_s_std,
470 };
471
472 static const struct v4l2_subdev_video_ops vpx3220_video_ops = {
473         .s_routing = vpx3220_s_routing,
474         .s_stream = vpx3220_s_stream,
475         .querystd = vpx3220_querystd,
476         .g_input_status = vpx3220_g_input_status,
477 };
478
479 static const struct v4l2_subdev_ops vpx3220_ops = {
480         .core = &vpx3220_core_ops,
481         .video = &vpx3220_video_ops,
482 };
483
484 /* -----------------------------------------------------------------------
485  * Client management code
486  */
487
488 static int vpx3220_probe(struct i2c_client *client,
489                         const struct i2c_device_id *id)
490 {
491         struct vpx3220 *decoder;
492         struct v4l2_subdev *sd;
493         const char *name = NULL;
494         u8 ver;
495         u16 pn;
496
497         /* Check if the adapter supports the needed features */
498         if (!i2c_check_functionality(client->adapter,
499                 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
500                 return -ENODEV;
501
502         decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
503         if (decoder == NULL)
504                 return -ENOMEM;
505         sd = &decoder->sd;
506         v4l2_i2c_subdev_init(sd, client, &vpx3220_ops);
507         decoder->norm = V4L2_STD_PAL;
508         decoder->input = 0;
509         decoder->enable = 1;
510         v4l2_ctrl_handler_init(&decoder->hdl, 4);
511         v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
512                 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
513         v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
514                 V4L2_CID_CONTRAST, 0, 63, 1, 32);
515         v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
516                 V4L2_CID_SATURATION, 0, 4095, 1, 2048);
517         v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
518                 V4L2_CID_HUE, -512, 511, 1, 0);
519         sd->ctrl_handler = &decoder->hdl;
520         if (decoder->hdl.error) {
521                 int err = decoder->hdl.error;
522
523                 v4l2_ctrl_handler_free(&decoder->hdl);
524                 kfree(decoder);
525                 return err;
526         }
527         v4l2_ctrl_handler_setup(&decoder->hdl);
528
529         ver = i2c_smbus_read_byte_data(client, 0x00);
530         pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
531                 i2c_smbus_read_byte_data(client, 0x01);
532         decoder->ident = V4L2_IDENT_VPX3220A;
533         if (ver == 0xec) {
534                 switch (pn) {
535                 case 0x4680:
536                         name = "vpx3220a";
537                         break;
538                 case 0x4260:
539                         name = "vpx3216b";
540                         decoder->ident = V4L2_IDENT_VPX3216B;
541                         break;
542                 case 0x4280:
543                         name = "vpx3214c";
544                         decoder->ident = V4L2_IDENT_VPX3214C;
545                         break;
546                 }
547         }
548         if (name)
549                 v4l2_info(sd, "%s found @ 0x%x (%s)\n", name,
550                         client->addr << 1, client->adapter->name);
551         else
552                 v4l2_info(sd, "chip (%02x:%04x) found @ 0x%x (%s)\n",
553                         ver, pn, client->addr << 1, client->adapter->name);
554
555         vpx3220_write_block(sd, init_common, sizeof(init_common));
556         vpx3220_write_fp_block(sd, init_fp, sizeof(init_fp) >> 1);
557         /* Default to PAL */
558         vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
559         return 0;
560 }
561
562 static int vpx3220_remove(struct i2c_client *client)
563 {
564         struct v4l2_subdev *sd = i2c_get_clientdata(client);
565         struct vpx3220 *decoder = to_vpx3220(sd);
566
567         v4l2_device_unregister_subdev(sd);
568         v4l2_ctrl_handler_free(&decoder->hdl);
569         kfree(decoder);
570         return 0;
571 }
572
573 static const struct i2c_device_id vpx3220_id[] = {
574         { "vpx3220a", 0 },
575         { "vpx3216b", 0 },
576         { "vpx3214c", 0 },
577         { }
578 };
579 MODULE_DEVICE_TABLE(i2c, vpx3220_id);
580
581 static struct i2c_driver vpx3220_driver = {
582         .driver = {
583                 .owner  = THIS_MODULE,
584                 .name   = "vpx3220",
585         },
586         .probe          = vpx3220_probe,
587         .remove         = vpx3220_remove,
588         .id_table       = vpx3220_id,
589 };
590
591 static __init int init_vpx3220(void)
592 {
593         return i2c_add_driver(&vpx3220_driver);
594 }
595
596 static __exit void exit_vpx3220(void)
597 {
598         i2c_del_driver(&vpx3220_driver);
599 }
600
601 module_init(init_vpx3220);
602 module_exit(exit_vpx3220);