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