]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/media/video/bt819.c
c6cfa7c48b04e5d5547437ab6703f61d25653dc2
[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/init.h>
33 #include <linux/delay.h>
34 #include <linux/errno.h>
35 #include <linux/fs.h>
36 #include <linux/kernel.h>
37 #include <linux/major.h>
38 #include <linux/slab.h>
39 #include <linux/mm.h>
40 #include <linux/pci.h>
41 #include <linux/signal.h>
42 #include <asm/io.h>
43 #include <asm/pgtable.h>
44 #include <asm/page.h>
45 #include <linux/sched.h>
46 #include <asm/segment.h>
47 #include <linux/types.h>
48
49 #include <linux/videodev.h>
50 #include <asm/uaccess.h>
51
52 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
53 MODULE_AUTHOR("Mike Bernson & Dave Perks");
54 MODULE_LICENSE("GPL");
55
56 #include <linux/i2c.h>
57 #include <linux/i2c-dev.h>
58
59 #define I2C_NAME(s) (s)->name
60
61 #include <linux/video_decoder.h>
62
63 static int debug = 0;
64 module_param(debug, int, 0);
65 MODULE_PARM_DESC(debug, "Debug level (0-1)");
66
67 #define dprintk(num, format, args...) \
68         do { \
69                 if (debug >= num) \
70                         printk(format, ##args); \
71         } while (0)
72
73 /* ----------------------------------------------------------------------- */
74
75 struct bt819 {
76         unsigned char reg[32];
77
78         int initialized;
79         int norm;
80         int input;
81         int enable;
82         int bright;
83         int contrast;
84         int hue;
85         int sat;
86 };
87
88 struct timing {
89         int hactive;
90         int hdelay;
91         int vactive;
92         int vdelay;
93         int hscale;
94         int vscale;
95 };
96
97 /* for values, see the bt819 datasheet */
98 static struct timing timing_data[] = {
99         {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
100         {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
101 };
102
103 #define   I2C_BT819        0x8a
104
105 /* ----------------------------------------------------------------------- */
106
107 static inline int
108 bt819_write (struct i2c_client *client,
109              u8                 reg,
110              u8                 value)
111 {
112         struct bt819 *decoder = i2c_get_clientdata(client);
113
114         decoder->reg[reg] = value;
115         return i2c_smbus_write_byte_data(client, reg, value);
116 }
117
118 static inline int
119 bt819_setbit (struct i2c_client *client,
120               u8                 reg,
121               u8                 bit,
122               u8                 value)
123 {
124         struct bt819 *decoder = i2c_get_clientdata(client);
125
126         return bt819_write(client, reg,
127                            (decoder->
128                             reg[reg] & ~(1 << bit)) |
129                             (value ? (1 << bit) : 0));
130 }
131
132 static int
133 bt819_write_block (struct i2c_client *client,
134                    const u8          *data,
135                    unsigned int       len)
136 {
137         int ret = -1;
138         u8 reg;
139
140         /* the bt819 has an autoincrement function, use it if
141          * the adapter understands raw I2C */
142         if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
143                 /* do raw I2C, not smbus compatible */
144                 struct bt819 *decoder = i2c_get_clientdata(client);
145                 struct i2c_msg msg;
146                 u8 block_data[32];
147
148                 msg.addr = client->addr;
149                 msg.flags = 0;
150                 while (len >= 2) {
151                         msg.buf = (char *) block_data;
152                         msg.len = 0;
153                         block_data[msg.len++] = reg = data[0];
154                         do {
155                                 block_data[msg.len++] =
156                                     decoder->reg[reg++] = data[1];
157                                 len -= 2;
158                                 data += 2;
159                         } while (len >= 2 && data[0] == reg &&
160                                  msg.len < 32);
161                         if ((ret = i2c_transfer(client->adapter,
162                                                 &msg, 1)) < 0)
163                                 break;
164                 }
165         } else {
166                 /* do some slow I2C emulation kind of thing */
167                 while (len >= 2) {
168                         reg = *data++;
169                         if ((ret = bt819_write(client, reg, *data++)) < 0)
170                                 break;
171                         len -= 2;
172                 }
173         }
174
175         return ret;
176 }
177
178 static inline int
179 bt819_read (struct i2c_client *client,
180             u8                 reg)
181 {
182         return i2c_smbus_read_byte_data(client, reg);
183 }
184
185 static int
186 bt819_init (struct i2c_client *client)
187 {
188         struct bt819 *decoder = i2c_get_clientdata(client);
189
190         static unsigned char init[] = {
191                 //0x1f, 0x00,     /* Reset */
192                 0x01, 0x59,     /* 0x01 input format */
193                 0x02, 0x00,     /* 0x02 temporal decimation */
194                 0x03, 0x12,     /* 0x03 Cropping msb */
195                 0x04, 0x16,     /* 0x04 Vertical Delay, lsb */
196                 0x05, 0xe0,     /* 0x05 Vertical Active lsb */
197                 0x06, 0x80,     /* 0x06 Horizontal Delay lsb */
198                 0x07, 0xd0,     /* 0x07 Horizontal Active lsb */
199                 0x08, 0x00,     /* 0x08 Horizontal Scaling msb */
200                 0x09, 0xf8,     /* 0x09 Horizontal Scaling lsb */
201                 0x0a, 0x00,     /* 0x0a Brightness control */
202                 0x0b, 0x30,     /* 0x0b Miscellaneous control */
203                 0x0c, 0xd8,     /* 0x0c Luma Gain lsb */
204                 0x0d, 0xfe,     /* 0x0d Chroma Gain (U) lsb */
205                 0x0e, 0xb4,     /* 0x0e Chroma Gain (V) msb */
206                 0x0f, 0x00,     /* 0x0f Hue control */
207                 0x12, 0x04,     /* 0x12 Output Format */
208                 0x13, 0x20,     /* 0x13 Vertial Scaling msb 0x00
209                                            chroma comb OFF, line drop scaling, interlace scaling
210                                            BUG? Why does turning the chroma comb on fuck up color?
211                                            Bug in the bt819 stepping on my board?
212                                         */
213                 0x14, 0x00,     /* 0x14 Vertial Scaling lsb */
214                 0x16, 0x07,     /* 0x16 Video Timing Polarity 
215                                            ACTIVE=active low
216                                            FIELD: high=odd, 
217                                            vreset=active high,
218                                            hreset=active high */
219                 0x18, 0x68,     /* 0x18 AGC Delay */
220                 0x19, 0x5d,     /* 0x19 Burst Gate Delay */
221                 0x1a, 0x80,     /* 0x1a ADC Interface */
222         };
223
224         struct timing *timing = &timing_data[decoder->norm];
225
226         init[0x03 * 2 - 1] =
227             (((timing->vdelay >> 8) & 0x03) << 6) | (((timing->
228                                                        vactive >> 8) &
229                                                       0x03) << 4) |
230             (((timing->hdelay >> 8) & 0x03) << 2) | ((timing->
231                                                       hactive >> 8) &
232                                                      0x03);
233         init[0x04 * 2 - 1] = timing->vdelay & 0xff;
234         init[0x05 * 2 - 1] = timing->vactive & 0xff;
235         init[0x06 * 2 - 1] = timing->hdelay & 0xff;
236         init[0x07 * 2 - 1] = timing->hactive & 0xff;
237         init[0x08 * 2 - 1] = timing->hscale >> 8;
238         init[0x09 * 2 - 1] = timing->hscale & 0xff;
239         /* 0x15 in array is address 0x19 */
240         init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93;   /* Chroma burst delay */
241         /* reset */
242         bt819_write(client, 0x1f, 0x00);
243         mdelay(1);
244
245         /* init */
246         return bt819_write_block(client, init, sizeof(init));
247
248 }
249
250 /* ----------------------------------------------------------------------- */
251
252 static int
253 bt819_command (struct i2c_client *client,
254                unsigned int       cmd,
255                void              *arg)
256 {
257         int temp;
258
259         struct bt819 *decoder = i2c_get_clientdata(client);
260
261         if (!decoder->initialized) {    // First call to bt819_init could be
262                 bt819_init(client);     // without #FRST = 0
263                 decoder->initialized = 1;
264         }
265
266         switch (cmd) {
267
268         case 0:
269                 /* This is just for testing!!! */
270                 bt819_init(client);
271                 break;
272
273         case DECODER_GET_CAPABILITIES:
274         {
275                 struct video_decoder_capability *cap = arg;
276
277                 cap->flags = VIDEO_DECODER_PAL |
278                              VIDEO_DECODER_NTSC |
279                              VIDEO_DECODER_AUTO |
280                              VIDEO_DECODER_CCIR;
281                 cap->inputs = 8;
282                 cap->outputs = 1;
283         }
284                 break;
285
286         case DECODER_GET_STATUS:
287         {
288                 int *iarg = arg;
289                 int status;
290                 int res;
291
292                 status = bt819_read(client, 0x00);
293                 res = 0;
294                 if ((status & 0x80)) {
295                         res |= DECODER_STATUS_GOOD;
296                 }
297                 switch (decoder->norm) {
298                 case VIDEO_MODE_NTSC:
299                         res |= DECODER_STATUS_NTSC;
300                         break;
301                 case VIDEO_MODE_PAL:
302                         res |= DECODER_STATUS_PAL;
303                         break;
304                 default:
305                 case VIDEO_MODE_AUTO:
306                         if ((status & 0x10)) {
307                                 res |= DECODER_STATUS_PAL;
308                         } else {
309                                 res |= DECODER_STATUS_NTSC;
310                         }
311                         break;
312                 }
313                 res |= DECODER_STATUS_COLOR;
314                 *iarg = res;
315
316                 dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
317                         *iarg);
318         }
319                 break;
320
321         case DECODER_SET_NORM:
322         {
323                 int *iarg = arg;
324                 struct timing *timing = NULL;
325
326                 dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
327                         *iarg);
328
329                 switch (*iarg) {
330                 case VIDEO_MODE_NTSC:
331                         bt819_setbit(client, 0x01, 0, 1);
332                         bt819_setbit(client, 0x01, 1, 0);
333                         bt819_setbit(client, 0x01, 5, 0);
334                         bt819_write(client, 0x18, 0x68);
335                         bt819_write(client, 0x19, 0x5d);
336                         //bt819_setbit(client, 0x1a,  5, 1);
337                         timing = &timing_data[VIDEO_MODE_NTSC];
338                         break;
339                 case VIDEO_MODE_PAL:
340                         bt819_setbit(client, 0x01, 0, 1);
341                         bt819_setbit(client, 0x01, 1, 1);
342                         bt819_setbit(client, 0x01, 5, 1);
343                         bt819_write(client, 0x18, 0x7f);
344                         bt819_write(client, 0x19, 0x72);
345                         //bt819_setbit(client, 0x1a,  5, 0);
346                         timing = &timing_data[VIDEO_MODE_PAL];
347                         break;
348                 case VIDEO_MODE_AUTO:
349                         bt819_setbit(client, 0x01, 0, 0);
350                         bt819_setbit(client, 0x01, 1, 0);
351                         break;
352                 default:
353                         dprintk(1,
354                                 KERN_ERR
355                                 "%s: unsupported norm %d\n",
356                                 I2C_NAME(client), *iarg);
357                         return -EINVAL;
358                 }
359
360                 if (timing) {
361                         bt819_write(client, 0x03,
362                                     (((timing->vdelay >> 8) & 0x03) << 6) |
363                                     (((timing->vactive >> 8) & 0x03) << 4) |
364                                     (((timing->hdelay >> 8) & 0x03) << 2) |
365                                      ((timing->hactive >> 8) & 0x03) );
366                         bt819_write(client, 0x04, timing->vdelay & 0xff);
367                         bt819_write(client, 0x05, timing->vactive & 0xff);
368                         bt819_write(client, 0x06, timing->hdelay & 0xff);
369                         bt819_write(client, 0x07, timing->hactive & 0xff);
370                         bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
371                         bt819_write(client, 0x09, timing->hscale & 0xff);
372                 }
373
374                 decoder->norm = *iarg;
375         }
376                 break;
377
378         case DECODER_SET_INPUT:
379         {
380                 int *iarg = arg;
381
382                 dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
383                         *iarg);
384
385                 if (*iarg < 0 || *iarg > 7) {
386                         return -EINVAL;
387                 }
388
389                 if (decoder->input != *iarg) {
390                         decoder->input = *iarg;
391                         /* select mode */
392                         if (decoder->input == 0) {
393                                 bt819_setbit(client, 0x0b, 6, 0);
394                                 bt819_setbit(client, 0x1a, 1, 1);
395                         } else {
396                                 bt819_setbit(client, 0x0b, 6, 1);
397                                 bt819_setbit(client, 0x1a, 1, 0);
398                         }
399                 }
400         }
401                 break;
402
403         case DECODER_SET_OUTPUT:
404         {
405                 int *iarg = arg;
406
407                 dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
408                         *iarg);
409
410                 /* not much choice of outputs */
411                 if (*iarg != 0) {
412                         return -EINVAL;
413                 }
414         }
415                 break;
416
417         case DECODER_ENABLE_OUTPUT:
418         {
419                 int *iarg = arg;
420                 int enable = (*iarg != 0);
421
422                 dprintk(1, KERN_INFO "%s: enable output %x\n",
423                         I2C_NAME(client), *iarg);
424
425                 if (decoder->enable != enable) {
426                         decoder->enable = enable;
427
428                         if (decoder->enable) {
429                                 bt819_setbit(client, 0x16, 7, 0);
430                         } else {
431                                 bt819_setbit(client, 0x16, 7, 1);
432                         }
433                 }
434         }
435                 break;
436
437         case DECODER_SET_PICTURE:
438         {
439                 struct video_picture *pic = arg;
440
441                 dprintk(1,
442                         KERN_INFO
443                         "%s: set picture brightness %d contrast %d colour %d\n",
444                         I2C_NAME(client), pic->brightness, pic->contrast,
445                         pic->colour);
446
447
448                 if (decoder->bright != pic->brightness) {
449                         /* We want -128 to 127 we get 0-65535 */
450                         decoder->bright = pic->brightness;
451                         bt819_write(client, 0x0a,
452                                     (decoder->bright >> 8) - 128);
453                 }
454
455                 if (decoder->contrast != pic->contrast) {
456                         /* We want 0 to 511 we get 0-65535 */
457                         decoder->contrast = pic->contrast;
458                         bt819_write(client, 0x0c,
459                                     (decoder->contrast >> 7) & 0xff);
460                         bt819_setbit(client, 0x0b, 2,
461                                      ((decoder->contrast >> 15) & 0x01));
462                 }
463
464                 if (decoder->sat != pic->colour) {
465                         /* We want 0 to 511 we get 0-65535 */
466                         decoder->sat = pic->colour;
467                         bt819_write(client, 0x0d,
468                                     (decoder->sat >> 7) & 0xff);
469                         bt819_setbit(client, 0x0b, 1,
470                                      ((decoder->sat >> 15) & 0x01));
471
472                         temp = (decoder->sat * 201) / 237;
473                         bt819_write(client, 0x0e, (temp >> 7) & 0xff);
474                         bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
475                 }
476
477                 if (decoder->hue != pic->hue) {
478                         /* We want -128 to 127 we get 0-65535 */
479                         decoder->hue = pic->hue;
480                         bt819_write(client, 0x0f,
481                                     128 - (decoder->hue >> 8));
482                 }
483         }
484                 break;
485
486         default:
487                 return -EINVAL;
488         }
489
490         return 0;
491 }
492
493 /* ----------------------------------------------------------------------- */
494
495 /*
496  * Generic i2c probe
497  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
498  */
499 static unsigned short normal_i2c[] = {
500         I2C_BT819 >> 1,
501         I2C_CLIENT_END,
502 };
503
504 static unsigned short ignore = I2C_CLIENT_END;
505                                                                                 
506 static struct i2c_client_address_data addr_data = {
507         .normal_i2c             = normal_i2c,
508         .probe                  = &ignore,
509         .ignore                 = &ignore,
510 };
511
512 static struct i2c_driver i2c_driver_bt819;
513
514 static int
515 bt819_detect_client (struct i2c_adapter *adapter,
516                      int                 address,
517                      int                 kind)
518 {
519         int i, id;
520         struct bt819 *decoder;
521         struct i2c_client *client;
522
523         dprintk(1,
524                 KERN_INFO
525                 "saa7111.c: detecting bt819 client on address 0x%x\n",
526                 address << 1);
527
528         /* Check if the adapter supports the needed features */
529         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
530                 return 0;
531
532         client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
533         if (client == 0)
534                 return -ENOMEM;
535         memset(client, 0, sizeof(struct i2c_client));
536         client->addr = address;
537         client->adapter = adapter;
538         client->driver = &i2c_driver_bt819;
539         client->flags = I2C_CLIENT_ALLOW_USE;
540
541         decoder = kmalloc(sizeof(struct bt819), GFP_KERNEL);
542         if (decoder == NULL) {
543                 kfree(client);
544                 return -ENOMEM;
545         }
546
547         memset(decoder, 0, sizeof(struct bt819));
548         decoder->norm = VIDEO_MODE_NTSC;
549         decoder->input = 0;
550         decoder->enable = 1;
551         decoder->bright = 32768;
552         decoder->contrast = 32768;
553         decoder->hue = 32768;
554         decoder->sat = 32768;
555         decoder->initialized = 0;
556         i2c_set_clientdata(client, decoder);
557
558         id = bt819_read(client, 0x17);
559         switch (id & 0xf0) {
560         case 0x70:
561                 strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
562                 break;
563         case 0x60:
564                 strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
565                 break;
566         case 0x20:
567                 strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
568                 break;
569         default:
570                 dprintk(1,
571                         KERN_ERR
572                         "bt819: unknown chip version 0x%x (ver 0x%x)\n",
573                         id & 0xf0, id & 0x0f);
574                 kfree(decoder);
575                 kfree(client);
576                 return 0;
577         }
578
579         i = i2c_attach_client(client);
580         if (i) {
581                 kfree(client);
582                 kfree(decoder);
583                 return i;
584         }
585
586         i = bt819_init(client);
587         if (i < 0) {
588                 dprintk(1, KERN_ERR "%s_attach: init status %d\n",
589                         I2C_NAME(client), i);
590         } else {
591                 dprintk(1,
592                         KERN_INFO
593                         "%s_attach: chip version 0x%x at address 0x%x\n",
594                         I2C_NAME(client), id & 0x0f,
595                         client->addr << 1);
596         }
597
598         return 0;
599 }
600
601 static int
602 bt819_attach_adapter (struct i2c_adapter *adapter)
603 {
604         return i2c_probe(adapter, &addr_data, &bt819_detect_client);
605 }
606
607 static int
608 bt819_detach_client (struct i2c_client *client)
609 {
610         struct bt819 *decoder = i2c_get_clientdata(client);
611         int err;
612
613         err = i2c_detach_client(client);
614         if (err) {
615                 return err;
616         }
617
618         kfree(decoder);
619         kfree(client);
620
621         return 0;
622 }
623
624 /* ----------------------------------------------------------------------- */
625
626 static struct i2c_driver i2c_driver_bt819 = {
627         .owner = THIS_MODULE,
628         .name = "bt819",
629
630         .id = I2C_DRIVERID_BT819,
631         .flags = I2C_DF_NOTIFY,
632
633         .attach_adapter = bt819_attach_adapter,
634         .detach_client = bt819_detach_client,
635         .command = bt819_command,
636 };
637
638 static int __init
639 bt819_init_module (void)
640 {
641         return i2c_add_driver(&i2c_driver_bt819);
642 }
643
644 static void __exit
645 bt819_exit (void)
646 {
647         i2c_del_driver(&i2c_driver_bt819);
648 }
649
650 module_init(bt819_init_module);
651 module_exit(bt819_exit);