Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6] / 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/delay.h>
33 #include <linux/types.h>
34 #include <linux/ioctl.h>
35 #include <asm/uaccess.h>
36 #include <linux/i2c.h>
37 #include <linux/i2c-id.h>
38 #include <linux/videodev.h>
39 #include <linux/video_decoder.h>
40 #include <media/v4l2-common.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 /* ----------------------------------------------------------------------- */
52
53 struct bt819 {
54         unsigned char reg[32];
55
56         int initialized;
57         int norm;
58         int input;
59         int enable;
60         int bright;
61         int contrast;
62         int hue;
63         int sat;
64 };
65
66 struct timing {
67         int hactive;
68         int hdelay;
69         int vactive;
70         int vdelay;
71         int hscale;
72         int vscale;
73 };
74
75 /* for values, see the bt819 datasheet */
76 static struct timing timing_data[] = {
77         {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
78         {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
79 };
80
81 /* ----------------------------------------------------------------------- */
82
83 static inline int bt819_write(struct i2c_client *client, u8 reg, u8 value)
84 {
85         struct bt819 *decoder = i2c_get_clientdata(client);
86
87         decoder->reg[reg] = value;
88         return i2c_smbus_write_byte_data(client, reg, value);
89 }
90
91 static inline int bt819_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
92 {
93         struct bt819 *decoder = i2c_get_clientdata(client);
94
95         return bt819_write(client, reg,
96                 (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
97 }
98
99 static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
100 {
101         int ret = -1;
102         u8 reg;
103
104         /* the bt819 has an autoincrement function, use it if
105          * the adapter understands raw I2C */
106         if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
107                 /* do raw I2C, not smbus compatible */
108                 struct bt819 *decoder = i2c_get_clientdata(client);
109                 u8 block_data[32];
110                 int block_len;
111
112                 while (len >= 2) {
113                         block_len = 0;
114                         block_data[block_len++] = reg = data[0];
115                         do {
116                                 block_data[block_len++] =
117                                     decoder->reg[reg++] = data[1];
118                                 len -= 2;
119                                 data += 2;
120                         } while (len >= 2 && data[0] == reg && block_len < 32);
121                         ret = i2c_master_send(client, block_data, block_len);
122                         if (ret < 0)
123                                 break;
124                 }
125         } else {
126                 /* do some slow I2C emulation kind of thing */
127                 while (len >= 2) {
128                         reg = *data++;
129                         if ((ret = bt819_write(client, reg, *data++)) < 0)
130                                 break;
131                         len -= 2;
132                 }
133         }
134
135         return ret;
136 }
137
138 static inline int bt819_read(struct i2c_client *client, u8 reg)
139 {
140         return i2c_smbus_read_byte_data(client, reg);
141 }
142
143 static int bt819_init(struct i2c_client *client)
144 {
145         struct bt819 *decoder = i2c_get_clientdata(client);
146
147         static unsigned char init[] = {
148                 /*0x1f, 0x00,*/     /* Reset */
149                 0x01, 0x59,     /* 0x01 input format */
150                 0x02, 0x00,     /* 0x02 temporal decimation */
151                 0x03, 0x12,     /* 0x03 Cropping msb */
152                 0x04, 0x16,     /* 0x04 Vertical Delay, lsb */
153                 0x05, 0xe0,     /* 0x05 Vertical Active lsb */
154                 0x06, 0x80,     /* 0x06 Horizontal Delay lsb */
155                 0x07, 0xd0,     /* 0x07 Horizontal Active lsb */
156                 0x08, 0x00,     /* 0x08 Horizontal Scaling msb */
157                 0x09, 0xf8,     /* 0x09 Horizontal Scaling lsb */
158                 0x0a, 0x00,     /* 0x0a Brightness control */
159                 0x0b, 0x30,     /* 0x0b Miscellaneous control */
160                 0x0c, 0xd8,     /* 0x0c Luma Gain lsb */
161                 0x0d, 0xfe,     /* 0x0d Chroma Gain (U) lsb */
162                 0x0e, 0xb4,     /* 0x0e Chroma Gain (V) msb */
163                 0x0f, 0x00,     /* 0x0f Hue control */
164                 0x12, 0x04,     /* 0x12 Output Format */
165                 0x13, 0x20,     /* 0x13 Vertial Scaling msb 0x00
166                                            chroma comb OFF, line drop scaling, interlace scaling
167                                            BUG? Why does turning the chroma comb on fuck up color?
168                                            Bug in the bt819 stepping on my board?
169                                         */
170                 0x14, 0x00,     /* 0x14 Vertial Scaling lsb */
171                 0x16, 0x07,     /* 0x16 Video Timing Polarity
172                                            ACTIVE=active low
173                                            FIELD: high=odd,
174                                            vreset=active high,
175                                            hreset=active high */
176                 0x18, 0x68,     /* 0x18 AGC Delay */
177                 0x19, 0x5d,     /* 0x19 Burst Gate Delay */
178                 0x1a, 0x80,     /* 0x1a ADC Interface */
179         };
180
181         struct timing *timing = &timing_data[decoder->norm];
182
183         init[0x03 * 2 - 1] =
184             (((timing->vdelay >> 8) & 0x03) << 6) |
185             (((timing->vactive >> 8) & 0x03) << 4) |
186             (((timing->hdelay >> 8) & 0x03) << 2) |
187             ((timing->hactive >> 8) & 0x03);
188         init[0x04 * 2 - 1] = timing->vdelay & 0xff;
189         init[0x05 * 2 - 1] = timing->vactive & 0xff;
190         init[0x06 * 2 - 1] = timing->hdelay & 0xff;
191         init[0x07 * 2 - 1] = timing->hactive & 0xff;
192         init[0x08 * 2 - 1] = timing->hscale >> 8;
193         init[0x09 * 2 - 1] = timing->hscale & 0xff;
194         /* 0x15 in array is address 0x19 */
195         init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93;   /* Chroma burst delay */
196         /* reset */
197         bt819_write(client, 0x1f, 0x00);
198         mdelay(1);
199
200         /* init */
201         return bt819_write_block(client, init, sizeof(init));
202 }
203
204 /* ----------------------------------------------------------------------- */
205
206 static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg)
207 {
208         int temp;
209
210         struct bt819 *decoder = i2c_get_clientdata(client);
211
212         if (!decoder->initialized) {    /* First call to bt819_init could be */
213                 bt819_init(client);     /* without #FRST = 0 */
214                 decoder->initialized = 1;
215         }
216
217         switch (cmd) {
218         case 0:
219                 /* This is just for testing!!! */
220                 bt819_init(client);
221                 break;
222
223         case DECODER_GET_CAPABILITIES:
224         {
225                 struct video_decoder_capability *cap = arg;
226
227                 cap->flags = VIDEO_DECODER_PAL |
228                              VIDEO_DECODER_NTSC |
229                              VIDEO_DECODER_AUTO |
230                              VIDEO_DECODER_CCIR;
231                 cap->inputs = 8;
232                 cap->outputs = 1;
233                 break;
234         }
235
236         case DECODER_GET_STATUS:
237         {
238                 int *iarg = arg;
239                 int status;
240                 int res;
241
242                 status = bt819_read(client, 0x00);
243                 res = 0;
244                 if ((status & 0x80))
245                         res |= DECODER_STATUS_GOOD;
246
247                 switch (decoder->norm) {
248                 case VIDEO_MODE_NTSC:
249                         res |= DECODER_STATUS_NTSC;
250                         break;
251                 case VIDEO_MODE_PAL:
252                         res |= DECODER_STATUS_PAL;
253                         break;
254                 default:
255                 case VIDEO_MODE_AUTO:
256                         if ((status & 0x10))
257                                 res |= DECODER_STATUS_PAL;
258                         else
259                                 res |= DECODER_STATUS_NTSC;
260                         break;
261                 }
262                 res |= DECODER_STATUS_COLOR;
263                 *iarg = res;
264
265                 v4l_dbg(1, debug, client, "get status %x\n", *iarg);
266                 break;
267         }
268
269         case DECODER_SET_NORM:
270         {
271                 int *iarg = arg;
272                 struct timing *timing = NULL;
273
274                 v4l_dbg(1, debug, client, "set norm %x\n", *iarg);
275
276                 switch (*iarg) {
277                 case VIDEO_MODE_NTSC:
278                         bt819_setbit(client, 0x01, 0, 1);
279                         bt819_setbit(client, 0x01, 1, 0);
280                         bt819_setbit(client, 0x01, 5, 0);
281                         bt819_write(client, 0x18, 0x68);
282                         bt819_write(client, 0x19, 0x5d);
283                         /* bt819_setbit(client, 0x1a,  5, 1); */
284                         timing = &timing_data[VIDEO_MODE_NTSC];
285                         break;
286                 case VIDEO_MODE_PAL:
287                         bt819_setbit(client, 0x01, 0, 1);
288                         bt819_setbit(client, 0x01, 1, 1);
289                         bt819_setbit(client, 0x01, 5, 1);
290                         bt819_write(client, 0x18, 0x7f);
291                         bt819_write(client, 0x19, 0x72);
292                         /* bt819_setbit(client, 0x1a,  5, 0); */
293                         timing = &timing_data[VIDEO_MODE_PAL];
294                         break;
295                 case VIDEO_MODE_AUTO:
296                         bt819_setbit(client, 0x01, 0, 0);
297                         bt819_setbit(client, 0x01, 1, 0);
298                         break;
299                 default:
300                         v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg);
301                         return -EINVAL;
302                 }
303
304                 if (timing) {
305                         bt819_write(client, 0x03,
306                                     (((timing->vdelay >> 8) & 0x03) << 6) |
307                                     (((timing->vactive >> 8) & 0x03) << 4) |
308                                     (((timing->hdelay >> 8) & 0x03) << 2) |
309                                      ((timing->hactive >> 8) & 0x03) );
310                         bt819_write(client, 0x04, timing->vdelay & 0xff);
311                         bt819_write(client, 0x05, timing->vactive & 0xff);
312                         bt819_write(client, 0x06, timing->hdelay & 0xff);
313                         bt819_write(client, 0x07, timing->hactive & 0xff);
314                         bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
315                         bt819_write(client, 0x09, timing->hscale & 0xff);
316                 }
317
318                 decoder->norm = *iarg;
319                 break;
320         }
321
322         case DECODER_SET_INPUT:
323         {
324                 int *iarg = arg;
325
326                 v4l_dbg(1, debug, client, "set input %x\n", *iarg);
327
328                 if (*iarg < 0 || *iarg > 7)
329                         return -EINVAL;
330
331                 if (decoder->input != *iarg) {
332                         decoder->input = *iarg;
333                         /* select mode */
334                         if (decoder->input == 0) {
335                                 bt819_setbit(client, 0x0b, 6, 0);
336                                 bt819_setbit(client, 0x1a, 1, 1);
337                         } else {
338                                 bt819_setbit(client, 0x0b, 6, 1);
339                                 bt819_setbit(client, 0x1a, 1, 0);
340                         }
341                 }
342                 break;
343         }
344
345         case DECODER_SET_OUTPUT:
346         {
347                 int *iarg = arg;
348
349                 v4l_dbg(1, debug, client, "set output %x\n", *iarg);
350
351                 /* not much choice of outputs */
352                 if (*iarg != 0)
353                         return -EINVAL;
354                 break;
355         }
356
357         case DECODER_ENABLE_OUTPUT:
358         {
359                 int *iarg = arg;
360                 int enable = (*iarg != 0);
361
362                 v4l_dbg(1, debug, client, "enable output %x\n", *iarg);
363
364                 if (decoder->enable != enable) {
365                         decoder->enable = enable;
366                         bt819_setbit(client, 0x16, 7, !enable);
367                 }
368                 break;
369         }
370
371         case DECODER_SET_PICTURE:
372         {
373                 struct video_picture *pic = arg;
374
375                 v4l_dbg(1, debug, client,
376                         "set picture brightness %d contrast %d colour %d\n",
377                         pic->brightness, pic->contrast, pic->colour);
378
379
380                 if (decoder->bright != pic->brightness) {
381                         /* We want -128 to 127 we get 0-65535 */
382                         decoder->bright = pic->brightness;
383                         bt819_write(client, 0x0a,
384                                     (decoder->bright >> 8) - 128);
385                 }
386
387                 if (decoder->contrast != pic->contrast) {
388                         /* We want 0 to 511 we get 0-65535 */
389                         decoder->contrast = pic->contrast;
390                         bt819_write(client, 0x0c,
391                                     (decoder->contrast >> 7) & 0xff);
392                         bt819_setbit(client, 0x0b, 2,
393                                      ((decoder->contrast >> 15) & 0x01));
394                 }
395
396                 if (decoder->sat != pic->colour) {
397                         /* We want 0 to 511 we get 0-65535 */
398                         decoder->sat = pic->colour;
399                         bt819_write(client, 0x0d,
400                                     (decoder->sat >> 7) & 0xff);
401                         bt819_setbit(client, 0x0b, 1,
402                                      ((decoder->sat >> 15) & 0x01));
403
404                         temp = (decoder->sat * 201) / 237;
405                         bt819_write(client, 0x0e, (temp >> 7) & 0xff);
406                         bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
407                 }
408
409                 if (decoder->hue != pic->hue) {
410                         /* We want -128 to 127 we get 0-65535 */
411                         decoder->hue = pic->hue;
412                         bt819_write(client, 0x0f,
413                                     128 - (decoder->hue >> 8));
414                 }
415                 break;
416         }
417
418         default:
419                 return -EINVAL;
420         }
421
422         return 0;
423 }
424
425 /* ----------------------------------------------------------------------- */
426
427 static unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END };
428
429 I2C_CLIENT_INSMOD;
430
431 static int bt819_probe(struct i2c_client *client,
432                         const struct i2c_device_id *id)
433 {
434         int i, ver;
435         struct bt819 *decoder;
436         const char *name;
437
438         /* Check if the adapter supports the needed features */
439         if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
440                 return -ENODEV;
441
442         ver = bt819_read(client, 0x17);
443         switch (ver & 0xf0) {
444         case 0x70:
445                 name = "bt819a";
446                 break;
447         case 0x60:
448                 name = "bt817a";
449                 break;
450         case 0x20:
451                 name = "bt815a";
452                 break;
453         default:
454                 v4l_dbg(1, debug, client,
455                         "unknown chip version 0x%02x\n", ver);
456                 return -ENODEV;
457         }
458
459         v4l_info(client, "%s found @ 0x%x (%s)\n", name,
460                         client->addr << 1, client->adapter->name);
461
462         decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
463         if (decoder == NULL)
464                 return -ENOMEM;
465         decoder->norm = VIDEO_MODE_NTSC;
466         decoder->input = 0;
467         decoder->enable = 1;
468         decoder->bright = 32768;
469         decoder->contrast = 32768;
470         decoder->hue = 32768;
471         decoder->sat = 32768;
472         decoder->initialized = 0;
473         i2c_set_clientdata(client, decoder);
474
475         i = bt819_init(client);
476         if (i < 0)
477                 v4l_dbg(1, debug, client, "init status %d\n", i);
478         return 0;
479 }
480
481 static int bt819_remove(struct i2c_client *client)
482 {
483         kfree(i2c_get_clientdata(client));
484         return 0;
485 }
486
487 /* ----------------------------------------------------------------------- */
488
489 static const struct i2c_device_id bt819_id[] = {
490         { "bt819a", 0 },
491         { "bt817a", 0 },
492         { "bt815a", 0 },
493         { }
494 };
495 MODULE_DEVICE_TABLE(i2c, bt819_id);
496
497 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
498         .name = "bt819",
499         .driverid = I2C_DRIVERID_BT819,
500         .command = bt819_command,
501         .probe = bt819_probe,
502         .remove = bt819_remove,
503         .id_table = bt819_id,
504 };