Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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         init[0x19*2-1] = decoder->norm == 0 ? 115 : 93; /* Chroma burst delay */
240         /* reset */
241         bt819_write(client, 0x1f, 0x00);
242         mdelay(1);
243 
244         /* init */
245         return bt819_write_block(client, init, sizeof(init));
246 
247 }
248 
249 /* ----------------------------------------------------------------------- */
250 
251 static int
252 bt819_command (struct i2c_client *client,
253                unsigned int       cmd,
254                void              *arg)
255 {
256         int temp;
257 
258         struct bt819 *decoder = i2c_get_clientdata(client);
259 
260         if (!decoder->initialized) {    // First call to bt819_init could be
261                 bt819_init(client);     // without #FRST = 0
262                 decoder->initialized = 1;
263         }
264 
265         switch (cmd) {
266 
267         case 0:
268                 /* This is just for testing!!! */
269                 bt819_init(client);
270                 break;
271 
272         case DECODER_GET_CAPABILITIES:
273         {
274                 struct video_decoder_capability *cap = arg;
275 
276                 cap->flags = VIDEO_DECODER_PAL |
277                              VIDEO_DECODER_NTSC |
278                              VIDEO_DECODER_AUTO |
279                              VIDEO_DECODER_CCIR;
280                 cap->inputs = 8;
281                 cap->outputs = 1;
282         }
283                 break;
284 
285         case DECODER_GET_STATUS:
286         {
287                 int *iarg = arg;
288                 int status;
289                 int res;
290 
291                 status = bt819_read(client, 0x00);
292                 res = 0;
293                 if ((status & 0x80)) {
294                         res |= DECODER_STATUS_GOOD;
295                 }
296                 switch (decoder->norm) {
297                 case VIDEO_MODE_NTSC:
298                         res |= DECODER_STATUS_NTSC;
299                         break;
300                 case VIDEO_MODE_PAL:
301                         res |= DECODER_STATUS_PAL;
302                         break;
303                 default:
304                 case VIDEO_MODE_AUTO:
305                         if ((status & 0x10)) {
306                                 res |= DECODER_STATUS_PAL;
307                         } else {
308                                 res |= DECODER_STATUS_NTSC;
309                         }
310                         break;
311                 }
312                 res |= DECODER_STATUS_COLOR;
313                 *iarg = res;
314 
315                 dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
316                         *iarg);
317         }
318                 break;
319 
320         case DECODER_SET_NORM:
321         {
322                 int *iarg = arg;
323                 struct timing *timing = NULL;
324 
325                 dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
326                         *iarg);
327 
328                 switch (*iarg) {
329                 case VIDEO_MODE_NTSC:
330                         bt819_setbit(client, 0x01, 0, 1);
331                         bt819_setbit(client, 0x01, 1, 0);
332                         bt819_setbit(client, 0x01, 5, 0);
333                         bt819_write(client, 0x18, 0x68);
334                         bt819_write(client, 0x19, 0x5d);
335                         //bt819_setbit(client, 0x1a,  5, 1);
336                         timing = &timing_data[VIDEO_MODE_NTSC];
337                         break;
338                 case VIDEO_MODE_PAL:
339                         bt819_setbit(client, 0x01, 0, 1);
340                         bt819_setbit(client, 0x01, 1, 1);
341                         bt819_setbit(client, 0x01, 5, 1);
342                         bt819_write(client, 0x18, 0x7f);
343                         bt819_write(client, 0x19, 0x72);
344                         //bt819_setbit(client, 0x1a,  5, 0);
345                         timing = &timing_data[VIDEO_MODE_PAL];
346                         break;
347                 case VIDEO_MODE_AUTO:
348                         bt819_setbit(client, 0x01, 0, 0);
349                         bt819_setbit(client, 0x01, 1, 0);
350                         break;
351                 default:
352                         dprintk(1,
353                                 KERN_ERR
354                                 "%s: unsupported norm %d\n",
355                                 I2C_NAME(client), *iarg);
356                         return -EINVAL;
357                 }
358 
359                 if (timing) {
360                         bt819_write(client, 0x03,
361                                     (((timing->vdelay >> 8) & 0x03) << 6) |
362                                     (((timing->vactive >> 8) & 0x03) << 4) |
363                                     (((timing->hdelay >> 8) & 0x03) << 2) |
364                                      ((timing->hactive >> 8) & 0x03) );
365                         bt819_write(client, 0x04, timing->vdelay & 0xff);
366                         bt819_write(client, 0x05, timing->vactive & 0xff);
367                         bt819_write(client, 0x06, timing->hdelay & 0xff);
368                         bt819_write(client, 0x07, timing->hactive & 0xff);
369                         bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
370                         bt819_write(client, 0x09, timing->hscale & 0xff);
371                 }
372 
373                 decoder->norm = *iarg;
374         }
375                 break;
376 
377         case DECODER_SET_INPUT:
378         {
379                 int *iarg = arg;
380 
381                 dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
382                         *iarg);
383 
384                 if (*iarg < 0 || *iarg > 7) {
385                         return -EINVAL;
386                 }
387 
388                 if (decoder->input != *iarg) {
389                         decoder->input = *iarg;
390                         /* select mode */
391                         if (decoder->input == 0) {
392                                 bt819_setbit(client, 0x0b, 6, 0);
393                                 bt819_setbit(client, 0x1a, 1, 1);
394                         } else {
395                                 bt819_setbit(client, 0x0b, 6, 1);
396                                 bt819_setbit(client, 0x1a, 1, 0);
397                         }
398                 }
399         }
400                 break;
401 
402         case DECODER_SET_OUTPUT:
403         {
404                 int *iarg = arg;
405 
406                 dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
407                         *iarg);
408 
409                 /* not much choice of outputs */
410                 if (*iarg != 0) {
411                         return -EINVAL;
412                 }
413         }
414                 break;
415 
416         case DECODER_ENABLE_OUTPUT:
417         {
418                 int *iarg = arg;
419                 int enable = (*iarg != 0);
420 
421                 dprintk(1, KERN_INFO "%s: enable output %x\n",
422                         I2C_NAME(client), *iarg);
423 
424                 if (decoder->enable != enable) {
425                         decoder->enable = enable;
426 
427                         if (decoder->enable) {
428                                 bt819_setbit(client, 0x16, 7, 0);
429                         } else {
430                                 bt819_setbit(client, 0x16, 7, 1);
431                         }
432                 }
433         }
434                 break;
435 
436         case DECODER_SET_PICTURE:
437         {
438                 struct video_picture *pic = arg;
439 
440                 dprintk(1,
441                         KERN_INFO
442                         "%s: set picture brightness %d contrast %d colour %d\n",
443                         I2C_NAME(client), pic->brightness, pic->contrast,
444                         pic->colour);
445 
446 
447                 if (decoder->bright != pic->brightness) {
448                         /* We want -128 to 127 we get 0-65535 */
449                         decoder->bright = pic->brightness;
450                         bt819_write(client, 0x0a,
451                                     (decoder->bright >> 8) - 128);
452                 }
453 
454                 if (decoder->contrast != pic->contrast) {
455                         /* We want 0 to 511 we get 0-65535 */
456                         decoder->contrast = pic->contrast;
457                         bt819_write(client, 0x0c,
458                                     (decoder->contrast >> 7) & 0xff);
459                         bt819_setbit(client, 0x0b, 2,
460                                      ((decoder->contrast >> 15) & 0x01));
461                 }
462 
463                 if (decoder->sat != pic->colour) {
464                         /* We want 0 to 511 we get 0-65535 */
465                         decoder->sat = pic->colour;
466                         bt819_write(client, 0x0d,
467                                     (decoder->sat >> 7) & 0xff);
468                         bt819_setbit(client, 0x0b, 1,
469                                      ((decoder->sat >> 15) & 0x01));
470 
471                         temp = (decoder->sat * 201) / 237;
472                         bt819_write(client, 0x0e, (temp >> 7) & 0xff);
473                         bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
474                 }
475 
476                 if (decoder->hue != pic->hue) {
477                         /* We want -128 to 127 we get 0-65535 */
478                         decoder->hue = pic->hue;
479                         bt819_write(client, 0x0f,
480                                     128 - (decoder->hue >> 8));
481                 }
482         }
483                 break;
484 
485         default:
486                 return -EINVAL;
487         }
488 
489         return 0;
490 }
491 
492 /* ----------------------------------------------------------------------- */
493 
494 /*
495  * Generic i2c probe
496  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
497  */
498 static unsigned short normal_i2c[] = {
499         I2C_BT819 >> 1,
500         I2C_CLIENT_END,
501 };
502 static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
503 
504 static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
505 static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
506 static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
507 static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
508 static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
509                                                                                 
510 static struct i2c_client_address_data addr_data = {
511         .normal_i2c             = normal_i2c,
512         .normal_i2c_range       = normal_i2c_range,
513         .probe                  = probe,
514         .probe_range            = probe_range,
515         .ignore                 = ignore,
516         .ignore_range           = ignore_range,
517         .force                  = force
518 };
519 
520 static int bt819_i2c_id = 0;
521 static struct i2c_driver i2c_driver_bt819;
522 
523 static int
524 bt819_detect_client (struct i2c_adapter *adapter,
525                      int                 address,
526                      int                 kind)
527 {
528         int i, id;
529         struct bt819 *decoder;
530         struct i2c_client *client;
531 
532         dprintk(1,
533                 KERN_INFO
534                 "saa7111.c: detecting bt819 client on address 0x%x\n",
535                 address << 1);
536 
537         /* Check if the adapter supports the needed features */
538         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
539                 return 0;
540 
541         client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
542         if (client == 0)
543                 return -ENOMEM;
544         memset(client, 0, sizeof(struct i2c_client));
545         client->addr = address;
546         client->adapter = adapter;
547         client->driver = &i2c_driver_bt819;
548         client->flags = I2C_CLIENT_ALLOW_USE;
549         client->id = bt819_i2c_id++;
550 
551         decoder = kmalloc(sizeof(struct bt819), GFP_KERNEL);
552         if (decoder == NULL) {
553                 kfree(client);
554                 return -ENOMEM;
555         }
556 
557         memset(decoder, 0, sizeof(struct bt819));
558         decoder->norm = VIDEO_MODE_NTSC;
559         decoder->input = 0;
560         decoder->enable = 1;
561         decoder->bright = 32768;
562         decoder->contrast = 32768;
563         decoder->hue = 32768;
564         decoder->sat = 32768;
565         decoder->initialized = 0;
566         i2c_set_clientdata(client, decoder);
567 
568         id = bt819_read(client, 0x17);
569         switch (id & 0xf0) {
570         case 0x70:
571                 snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1,
572                          "bt819a[%d]", client->id);
573                 break;
574         case 0x60:
575                 snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1,
576                          "bt817a[%d]", client->id);
577                 break;
578         case 0x20:
579                 snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1,
580                          "bt815a[%d]", client->id);
581                 break;
582         default:
583                 dprintk(1,
584                         KERN_ERR
585                         "bt819: unknown chip version 0x%x (ver 0x%x)\n",
586                         id & 0xf0, id & 0x0f);
587                 kfree(decoder);
588                 kfree(client);
589                 return 0;
590         }
591 
592         i = i2c_attach_client(client);
593         if (i) {
594                 kfree(client);
595                 kfree(decoder);
596                 return i;
597         }
598 
599         i = bt819_init(client);
600         if (i < 0) {
601                 dprintk(1, KERN_ERR "%s_attach: init status %d\n",
602                         I2C_NAME(client), i);
603         } else {
604                 dprintk(1,
605                         KERN_INFO
606                         "%s_attach: chip version 0x%x at address 0x%x\n",
607                         I2C_NAME(client), id & 0x0f,
608                         client->addr << 1);
609         }
610 
611         return 0;
612 }
613 
614 static int
615 bt819_attach_adapter (struct i2c_adapter *adapter)
616 {
617         return i2c_probe(adapter, &addr_data, &bt819_detect_client);
618 }
619 
620 static int
621 bt819_detach_client (struct i2c_client *client)
622 {
623         struct bt819 *decoder = i2c_get_clientdata(client);
624         int err;
625 
626         err = i2c_detach_client(client);
627         if (err) {
628                 return err;
629         }
630 
631         kfree(decoder);
632         kfree(client);
633 
634         return 0;
635 }
636 
637 /* ----------------------------------------------------------------------- */
638 
639 static struct i2c_driver i2c_driver_bt819 = {
640         .owner = THIS_MODULE,
641         .name = "bt819",
642 
643         .id = I2C_DRIVERID_BT819,
644         .flags = I2C_DF_NOTIFY,
645 
646         .attach_adapter = bt819_attach_adapter,
647         .detach_client = bt819_detach_client,
648         .command = bt819_command,
649 };
650 
651 static int __init
652 bt819_init_module (void)
653 {
654         return i2c_add_driver(&i2c_driver_bt819);
655 }
656 
657 static void __exit
658 bt819_exit (void)
659 {
660         i2c_del_driver(&i2c_driver_bt819);
661 }
662 
663 module_init(bt819_init_module);
664 module_exit(bt819_exit);
665 
  This page was automatically generated by the LXR engine.