]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/media/video/bt819.c
V4L/DVB (10719): bt819: convert to v4l2_subdev.
[karo-tx-linux.git] / drivers / media / video / bt819.c
1 /*
2  *  bt819 - BT819A VideoStream Decoder (Rockwell Part)
3  *
4  * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5  * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
6  *
7  * Modifications for LML33/DC10plus unified driver
8  * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9  *
10  * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
11  *    - moved over to linux>=2.4.x i2c protocol (9/9/2002)
12  *
13  * This code was modify/ported from the saa7111 driver written
14  * by Dave Perks.
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 2 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29  */
30
31 #include <linux/module.h>
32 #include <linux/types.h>
33 #include <linux/ioctl.h>
34 #include <asm/uaccess.h>
35 #include <linux/i2c.h>
36 #include <linux/i2c-id.h>
37 #include <linux/videodev2.h>
38 #include <media/v4l2-device.h>
39 #include <media/v4l2-chip-ident.h>
40 #include <media/v4l2-i2c-drv-legacy.h>
41
42 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
43 MODULE_AUTHOR("Mike Bernson & Dave Perks");
44 MODULE_LICENSE("GPL");
45
46 static int debug;
47 module_param(debug, int, 0);
48 MODULE_PARM_DESC(debug, "Debug level (0-1)");
49
50 static unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END };
51
52 I2C_CLIENT_INSMOD;
53
54 /* ----------------------------------------------------------------------- */
55
56 struct bt819 {
57         struct v4l2_subdev sd;
58         unsigned char reg[32];
59
60         v4l2_std_id norm;
61         int ident;
62         int input;
63         int enable;
64         int bright;
65         int contrast;
66         int hue;
67         int sat;
68 };
69
70 static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
71 {
72         return container_of(sd, struct bt819, sd);
73 }
74
75 struct timing {
76         int hactive;
77         int hdelay;
78         int vactive;
79         int vdelay;
80         int hscale;
81         int vscale;
82 };
83
84 /* for values, see the bt819 datasheet */
85 static struct timing timing_data[] = {
86         {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
87         {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
88 };
89
90 /* ----------------------------------------------------------------------- */
91
92 static inline int bt819_write(struct bt819 *decoder, u8 reg, u8 value)
93 {
94         struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
95
96         decoder->reg[reg] = value;
97         return i2c_smbus_write_byte_data(client, reg, value);
98 }
99
100 static inline int bt819_setbit(struct bt819 *decoder, u8 reg, u8 bit, u8 value)
101 {
102         return bt819_write(decoder, reg,
103                 (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
104 }
105
106 static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int len)
107 {
108         struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
109         int ret = -1;
110         u8 reg;
111
112         /* the bt819 has an autoincrement function, use it if
113          * the adapter understands raw I2C */
114         if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
115                 /* do raw I2C, not smbus compatible */
116                 u8 block_data[32];
117                 int block_len;
118
119                 while (len >= 2) {
120                         block_len = 0;
121                         block_data[block_len++] = reg = data[0];
122                         do {
123                                 block_data[block_len++] =
124                                     decoder->reg[reg++] = data[1];
125                                 len -= 2;
126                                 data += 2;
127                         } while (len >= 2 && data[0] == reg && block_len < 32);
128                         ret = i2c_master_send(client, block_data, block_len);
129                         if (ret < 0)
130                                 break;
131                 }
132         } else {
133                 /* do some slow I2C emulation kind of thing */
134                 while (len >= 2) {
135                         reg = *data++;
136                         ret = bt819_write(decoder, reg, *data++);
137                         if (ret < 0)
138                                 break;
139                         len -= 2;
140                 }
141         }
142
143         return ret;
144 }
145
146 static inline int bt819_read(struct bt819 *decoder, u8 reg)
147 {
148         struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
149
150         return i2c_smbus_read_byte_data(client, reg);
151 }
152
153 static int bt819_init(struct v4l2_subdev *sd)
154 {
155         static unsigned char init[] = {
156                 /*0x1f, 0x00,*/     /* Reset */
157                 0x01, 0x59,     /* 0x01 input format */
158                 0x02, 0x00,     /* 0x02 temporal decimation */
159                 0x03, 0x12,     /* 0x03 Cropping msb */
160                 0x04, 0x16,     /* 0x04 Vertical Delay, lsb */
161                 0x05, 0xe0,     /* 0x05 Vertical Active lsb */
162                 0x06, 0x80,     /* 0x06 Horizontal Delay lsb */
163                 0x07, 0xd0,     /* 0x07 Horizontal Active lsb */
164                 0x08, 0x00,     /* 0x08 Horizontal Scaling msb */
165                 0x09, 0xf8,     /* 0x09 Horizontal Scaling lsb */
166                 0x0a, 0x00,     /* 0x0a Brightness control */
167                 0x0b, 0x30,     /* 0x0b Miscellaneous control */
168                 0x0c, 0xd8,     /* 0x0c Luma Gain lsb */
169                 0x0d, 0xfe,     /* 0x0d Chroma Gain (U) lsb */
170                 0x0e, 0xb4,     /* 0x0e Chroma Gain (V) msb */
171                 0x0f, 0x00,     /* 0x0f Hue control */
172                 0x12, 0x04,     /* 0x12 Output Format */
173                 0x13, 0x20,     /* 0x13 Vertial Scaling msb 0x00
174                                            chroma comb OFF, line drop scaling, interlace scaling
175                                            BUG? Why does turning the chroma comb on fuck up color?
176                                            Bug in the bt819 stepping on my board?
177                                         */
178                 0x14, 0x00,     /* 0x14 Vertial Scaling lsb */
179                 0x16, 0x07,     /* 0x16 Video Timing Polarity
180                                            ACTIVE=active low
181                                            FIELD: high=odd,
182                                            vreset=active high,
183                                            hreset=active high */
184                 0x18, 0x68,     /* 0x18 AGC Delay */
185                 0x19, 0x5d,     /* 0x19 Burst Gate Delay */
186                 0x1a, 0x80,     /* 0x1a ADC Interface */
187         };
188
189         struct bt819 *decoder = to_bt819(sd);
190         struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0];
191
192         init[0x03 * 2 - 1] =
193             (((timing->vdelay >> 8) & 0x03) << 6) |
194             (((timing->vactive >> 8) & 0x03) << 4) |
195             (((timing->hdelay >> 8) & 0x03) << 2) |
196             ((timing->hactive >> 8) & 0x03);
197         init[0x04 * 2 - 1] = timing->vdelay & 0xff;
198         init[0x05 * 2 - 1] = timing->vactive & 0xff;
199         init[0x06 * 2 - 1] = timing->hdelay & 0xff;
200         init[0x07 * 2 - 1] = timing->hactive & 0xff;
201         init[0x08 * 2 - 1] = timing->hscale >> 8;
202         init[0x09 * 2 - 1] = timing->hscale & 0xff;
203         /* 0x15 in array is address 0x19 */
204         init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93;      /* Chroma burst delay */
205         /* reset */
206         bt819_write(decoder, 0x1f, 0x00);
207         mdelay(1);
208
209         /* init */
210         return bt819_write_block(decoder, init, sizeof(init));
211 }
212
213 /* ----------------------------------------------------------------------- */
214
215 static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
216 {
217         struct bt819 *decoder = to_bt819(sd);
218         int status = bt819_read(decoder, 0x00);
219         int res = V4L2_IN_ST_NO_SIGNAL;
220         v4l2_std_id std;
221
222         if ((status & 0x80))
223                 res = 0;
224
225         if ((status & 0x10))
226                 std = V4L2_STD_PAL;
227         else
228                 std = V4L2_STD_NTSC;
229         if (pstd)
230                 *pstd = std;
231         if (pstatus)
232                 *pstatus = status;
233
234         v4l2_dbg(1, debug, sd, "get status %x\n", status);
235         return 0;
236 }
237
238 static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
239 {
240         return bt819_status(sd, NULL, std);
241 }
242
243 static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status)
244 {
245         return bt819_status(sd, status, NULL);
246 }
247
248 static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
249 {
250         struct bt819 *decoder = to_bt819(sd);
251         struct timing *timing = NULL;
252
253         v4l2_dbg(1, debug, sd, "set norm %llx\n", std);
254
255         if (std & V4L2_STD_NTSC) {
256                 bt819_setbit(decoder, 0x01, 0, 1);
257                 bt819_setbit(decoder, 0x01, 1, 0);
258                 bt819_setbit(decoder, 0x01, 5, 0);
259                 bt819_write(decoder, 0x18, 0x68);
260                 bt819_write(decoder, 0x19, 0x5d);
261                 /* bt819_setbit(decoder, 0x1a,  5, 1); */
262                 timing = &timing_data[1];
263         } else if (std & V4L2_STD_PAL) {
264                 bt819_setbit(decoder, 0x01, 0, 1);
265                 bt819_setbit(decoder, 0x01, 1, 1);
266                 bt819_setbit(decoder, 0x01, 5, 1);
267                 bt819_write(decoder, 0x18, 0x7f);
268                 bt819_write(decoder, 0x19, 0x72);
269                 /* bt819_setbit(decoder, 0x1a,  5, 0); */
270                 timing = &timing_data[0];
271         } else {
272                 v4l2_dbg(1, debug, sd, "unsupported norm %llx\n", std);
273                 return -EINVAL;
274         }
275         bt819_write(decoder, 0x03,
276                         (((timing->vdelay >> 8) & 0x03) << 6) |
277                         (((timing->vactive >> 8) & 0x03) << 4) |
278                         (((timing->hdelay >> 8) & 0x03) << 2) |
279                         ((timing->hactive >> 8) & 0x03));
280         bt819_write(decoder, 0x04, timing->vdelay & 0xff);
281         bt819_write(decoder, 0x05, timing->vactive & 0xff);
282         bt819_write(decoder, 0x06, timing->hdelay & 0xff);
283         bt819_write(decoder, 0x07, timing->hactive & 0xff);
284         bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff);
285         bt819_write(decoder, 0x09, timing->hscale & 0xff);
286         decoder->norm = std;
287         return 0;
288 }
289
290 static int bt819_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
291 {
292         struct bt819 *decoder = to_bt819(sd);
293
294         v4l2_dbg(1, debug, sd, "set input %x\n", route->input);
295
296         if (route->input < 0 || route->input > 7)
297                 return -EINVAL;
298
299         if (decoder->input != route->input) {
300                 decoder->input = route->input;
301                 /* select mode */
302                 if (decoder->input == 0) {
303                         bt819_setbit(decoder, 0x0b, 6, 0);
304                         bt819_setbit(decoder, 0x1a, 1, 1);
305                 } else {
306                         bt819_setbit(decoder, 0x0b, 6, 1);
307                         bt819_setbit(decoder, 0x1a, 1, 0);
308                 }
309         }
310         return 0;
311 }
312
313 static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
314 {
315         struct bt819 *decoder = to_bt819(sd);
316
317         v4l2_dbg(1, debug, sd, "enable output %x\n", enable);
318
319         if (decoder->enable != enable) {
320                 decoder->enable = enable;
321                 bt819_setbit(decoder, 0x16, 7, !enable);
322         }
323         return 0;
324 }
325
326 static int bt819_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
327 {
328         switch (qc->id) {
329         case V4L2_CID_BRIGHTNESS:
330                 v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
331                 break;
332
333         case V4L2_CID_CONTRAST:
334                 v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
335                 break;
336
337         case V4L2_CID_SATURATION:
338                 v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
339                 break;
340
341         case V4L2_CID_HUE:
342                 v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
343                 break;
344
345         default:
346                 return -EINVAL;
347         }
348         return 0;
349 }
350
351 static int bt819_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
352 {
353         struct bt819 *decoder = to_bt819(sd);
354         int temp;
355
356         switch (ctrl->id) {
357         case V4L2_CID_BRIGHTNESS:
358                 if (decoder->bright == ctrl->value)
359                         break;
360                 decoder->bright = ctrl->value;
361                 bt819_write(decoder, 0x0a, decoder->bright);
362                 break;
363
364         case V4L2_CID_CONTRAST:
365                 if (decoder->contrast == ctrl->value)
366                         break;
367                 decoder->contrast = ctrl->value;
368                 bt819_write(decoder, 0x0c, decoder->contrast & 0xff);
369                 bt819_setbit(decoder, 0x0b, 2, ((decoder->contrast >> 8) & 0x01));
370                 break;
371
372         case V4L2_CID_SATURATION:
373                 if (decoder->sat == ctrl->value)
374                         break;
375                 decoder->sat = ctrl->value;
376                 bt819_write(decoder, 0x0d, (decoder->sat >> 7) & 0xff);
377                 bt819_setbit(decoder, 0x0b, 1, ((decoder->sat >> 15) & 0x01));
378
379                 /* Ratio between U gain and V gain must stay the same as
380                    the ratio between the default U and V gain values. */
381                 temp = (decoder->sat * 180) / 254;
382                 bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
383                 bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
384                 break;
385
386         case V4L2_CID_HUE:
387                 if (decoder->hue == ctrl->value)
388                         break;
389                 decoder->hue = ctrl->value;
390                 bt819_write(decoder, 0x0f, decoder->hue);
391                 break;
392
393         default:
394                 return -EINVAL;
395         }
396         return 0;
397 }
398
399 static int bt819_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
400 {
401         struct bt819 *decoder = to_bt819(sd);
402
403         switch (ctrl->id) {
404         case V4L2_CID_BRIGHTNESS:
405                 ctrl->value = decoder->bright;
406                 break;
407         case V4L2_CID_CONTRAST:
408                 ctrl->value = decoder->contrast;
409                 break;
410         case V4L2_CID_SATURATION:
411                 ctrl->value = decoder->sat;
412                 break;
413         case V4L2_CID_HUE:
414                 ctrl->value = decoder->hue;
415                 break;
416         default:
417                 return -EINVAL;
418         }
419         return 0;
420 }
421
422 static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
423 {
424         struct bt819 *decoder = to_bt819(sd);
425         struct i2c_client *client = v4l2_get_subdevdata(sd);
426
427         return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
428 }
429
430 static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg)
431 {
432         return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
433 }
434
435 /* ----------------------------------------------------------------------- */
436
437 static const struct v4l2_subdev_core_ops bt819_core_ops = {
438         .g_chip_ident = bt819_g_chip_ident,
439         .g_ctrl = bt819_g_ctrl,
440         .s_ctrl = bt819_s_ctrl,
441         .queryctrl = bt819_queryctrl,
442 };
443
444 static const struct v4l2_subdev_tuner_ops bt819_tuner_ops = {
445         .s_std = bt819_s_std,
446 };
447
448 static const struct v4l2_subdev_video_ops bt819_video_ops = {
449         .s_routing = bt819_s_routing,
450         .s_stream = bt819_s_stream,
451         .querystd = bt819_querystd,
452         .g_input_status = bt819_g_input_status,
453 };
454
455 static const struct v4l2_subdev_ops bt819_ops = {
456         .core = &bt819_core_ops,
457         .tuner = &bt819_tuner_ops,
458         .video = &bt819_video_ops,
459 };
460
461 /* ----------------------------------------------------------------------- */
462
463 static int bt819_probe(struct i2c_client *client,
464                         const struct i2c_device_id *id)
465 {
466         int i, ver;
467         struct bt819 *decoder;
468         struct v4l2_subdev *sd;
469         const char *name;
470
471         /* Check if the adapter supports the needed features */
472         if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
473                 return -ENODEV;
474
475         decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
476         if (decoder == NULL)
477                 return -ENOMEM;
478         sd = &decoder->sd;
479         v4l2_i2c_subdev_init(sd, client, &bt819_ops);
480
481         ver = bt819_read(decoder, 0x17);
482         switch (ver & 0xf0) {
483         case 0x70:
484                 name = "bt819a";
485                 decoder->ident = V4L2_IDENT_BT819A;
486                 break;
487         case 0x60:
488                 name = "bt817a";
489                 decoder->ident = V4L2_IDENT_BT817A;
490                 break;
491         case 0x20:
492                 name = "bt815a";
493                 decoder->ident = V4L2_IDENT_BT815A;
494                 break;
495         default:
496                 v4l2_dbg(1, debug, sd,
497                         "unknown chip version 0x%02x\n", ver);
498                 return -ENODEV;
499         }
500
501         v4l_info(client, "%s found @ 0x%x (%s)\n", name,
502                         client->addr << 1, client->adapter->name);
503
504         decoder->norm = V4L2_STD_NTSC;
505         decoder->input = 0;
506         decoder->enable = 1;
507         decoder->bright = 0;
508         decoder->contrast = 0xd8;       /* 100% of original signal */
509         decoder->hue = 0;
510         decoder->sat = 0xfe;            /* 100% of original signal */
511
512         i = bt819_init(sd);
513         if (i < 0)
514                 v4l2_dbg(1, debug, sd, "init status %d\n", i);
515         return 0;
516 }
517
518 static int bt819_remove(struct i2c_client *client)
519 {
520         struct v4l2_subdev *sd = i2c_get_clientdata(client);
521
522         v4l2_device_unregister_subdev(sd);
523         kfree(to_bt819(sd));
524         return 0;
525 }
526
527 /* ----------------------------------------------------------------------- */
528
529 static const struct i2c_device_id bt819_id[] = {
530         { "bt819a", 0 },
531         { "bt817a", 0 },
532         { "bt815a", 0 },
533         { }
534 };
535 MODULE_DEVICE_TABLE(i2c, bt819_id);
536
537 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
538         .name = "bt819",
539         .driverid = I2C_DRIVERID_BT819,
540         .command = bt819_command,
541         .probe = bt819_probe,
542         .remove = bt819_remove,
543         .id_table = bt819_id,
544 };