Linux 2.6.17.7
[linux/fpc-iii.git] / drivers / media / video / bt819.c
blobe7b38fdd5e3c9389e2032ca1c8c5103a19a120a1
1 /*
2 * bt819 - BT819A VideoStream Decoder (Rockwell Part)
4 * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
7 * Modifications for LML33/DC10plus unified driver
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
10 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
11 * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
13 * This code was modify/ported from the saa7111 driver written
14 * by Dave Perks.
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.
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.
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.
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 <linux/types.h>
48 #include <linux/videodev.h>
49 #include <asm/uaccess.h>
51 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
52 MODULE_AUTHOR("Mike Bernson & Dave Perks");
53 MODULE_LICENSE("GPL");
55 #include <linux/i2c.h>
57 #define I2C_NAME(s) (s)->name
59 #include <linux/video_decoder.h>
61 static int debug = 0;
62 module_param(debug, int, 0);
63 MODULE_PARM_DESC(debug, "Debug level (0-1)");
65 #define dprintk(num, format, args...) \
66 do { \
67 if (debug >= num) \
68 printk(format, ##args); \
69 } while (0)
71 /* ----------------------------------------------------------------------- */
73 struct bt819 {
74 unsigned char reg[32];
76 int initialized;
77 int norm;
78 int input;
79 int enable;
80 int bright;
81 int contrast;
82 int hue;
83 int sat;
86 struct timing {
87 int hactive;
88 int hdelay;
89 int vactive;
90 int vdelay;
91 int hscale;
92 int vscale;
95 /* for values, see the bt819 datasheet */
96 static struct timing timing_data[] = {
97 {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
98 {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
101 #define I2C_BT819 0x8a
103 /* ----------------------------------------------------------------------- */
105 static inline int
106 bt819_write (struct i2c_client *client,
107 u8 reg,
108 u8 value)
110 struct bt819 *decoder = i2c_get_clientdata(client);
112 decoder->reg[reg] = value;
113 return i2c_smbus_write_byte_data(client, reg, value);
116 static inline int
117 bt819_setbit (struct i2c_client *client,
118 u8 reg,
119 u8 bit,
120 u8 value)
122 struct bt819 *decoder = i2c_get_clientdata(client);
124 return bt819_write(client, reg,
125 (decoder->
126 reg[reg] & ~(1 << bit)) |
127 (value ? (1 << bit) : 0));
130 static int
131 bt819_write_block (struct i2c_client *client,
132 const u8 *data,
133 unsigned int len)
135 int ret = -1;
136 u8 reg;
138 /* the bt819 has an autoincrement function, use it if
139 * the adapter understands raw I2C */
140 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
141 /* do raw I2C, not smbus compatible */
142 struct bt819 *decoder = i2c_get_clientdata(client);
143 u8 block_data[32];
144 int block_len;
146 while (len >= 2) {
147 block_len = 0;
148 block_data[block_len++] = reg = data[0];
149 do {
150 block_data[block_len++] =
151 decoder->reg[reg++] = data[1];
152 len -= 2;
153 data += 2;
154 } while (len >= 2 && data[0] == reg &&
155 block_len < 32);
156 if ((ret = i2c_master_send(client, block_data,
157 block_len)) < 0)
158 break;
160 } else {
161 /* do some slow I2C emulation kind of thing */
162 while (len >= 2) {
163 reg = *data++;
164 if ((ret = bt819_write(client, reg, *data++)) < 0)
165 break;
166 len -= 2;
170 return ret;
173 static inline int
174 bt819_read (struct i2c_client *client,
175 u8 reg)
177 return i2c_smbus_read_byte_data(client, reg);
180 static int
181 bt819_init (struct i2c_client *client)
183 struct bt819 *decoder = i2c_get_clientdata(client);
185 static unsigned char init[] = {
186 //0x1f, 0x00, /* Reset */
187 0x01, 0x59, /* 0x01 input format */
188 0x02, 0x00, /* 0x02 temporal decimation */
189 0x03, 0x12, /* 0x03 Cropping msb */
190 0x04, 0x16, /* 0x04 Vertical Delay, lsb */
191 0x05, 0xe0, /* 0x05 Vertical Active lsb */
192 0x06, 0x80, /* 0x06 Horizontal Delay lsb */
193 0x07, 0xd0, /* 0x07 Horizontal Active lsb */
194 0x08, 0x00, /* 0x08 Horizontal Scaling msb */
195 0x09, 0xf8, /* 0x09 Horizontal Scaling lsb */
196 0x0a, 0x00, /* 0x0a Brightness control */
197 0x0b, 0x30, /* 0x0b Miscellaneous control */
198 0x0c, 0xd8, /* 0x0c Luma Gain lsb */
199 0x0d, 0xfe, /* 0x0d Chroma Gain (U) lsb */
200 0x0e, 0xb4, /* 0x0e Chroma Gain (V) msb */
201 0x0f, 0x00, /* 0x0f Hue control */
202 0x12, 0x04, /* 0x12 Output Format */
203 0x13, 0x20, /* 0x13 Vertial Scaling msb 0x00
204 chroma comb OFF, line drop scaling, interlace scaling
205 BUG? Why does turning the chroma comb on fuck up color?
206 Bug in the bt819 stepping on my board?
208 0x14, 0x00, /* 0x14 Vertial Scaling lsb */
209 0x16, 0x07, /* 0x16 Video Timing Polarity
210 ACTIVE=active low
211 FIELD: high=odd,
212 vreset=active high,
213 hreset=active high */
214 0x18, 0x68, /* 0x18 AGC Delay */
215 0x19, 0x5d, /* 0x19 Burst Gate Delay */
216 0x1a, 0x80, /* 0x1a ADC Interface */
219 struct timing *timing = &timing_data[decoder->norm];
221 init[0x03 * 2 - 1] =
222 (((timing->vdelay >> 8) & 0x03) << 6) | (((timing->
223 vactive >> 8) &
224 0x03) << 4) |
225 (((timing->hdelay >> 8) & 0x03) << 2) | ((timing->
226 hactive >> 8) &
227 0x03);
228 init[0x04 * 2 - 1] = timing->vdelay & 0xff;
229 init[0x05 * 2 - 1] = timing->vactive & 0xff;
230 init[0x06 * 2 - 1] = timing->hdelay & 0xff;
231 init[0x07 * 2 - 1] = timing->hactive & 0xff;
232 init[0x08 * 2 - 1] = timing->hscale >> 8;
233 init[0x09 * 2 - 1] = timing->hscale & 0xff;
234 /* 0x15 in array is address 0x19 */
235 init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93; /* Chroma burst delay */
236 /* reset */
237 bt819_write(client, 0x1f, 0x00);
238 mdelay(1);
240 /* init */
241 return bt819_write_block(client, init, sizeof(init));
245 /* ----------------------------------------------------------------------- */
247 static int
248 bt819_command (struct i2c_client *client,
249 unsigned int cmd,
250 void *arg)
252 int temp;
254 struct bt819 *decoder = i2c_get_clientdata(client);
256 if (!decoder->initialized) { // First call to bt819_init could be
257 bt819_init(client); // without #FRST = 0
258 decoder->initialized = 1;
261 switch (cmd) {
263 case 0:
264 /* This is just for testing!!! */
265 bt819_init(client);
266 break;
268 case DECODER_GET_CAPABILITIES:
270 struct video_decoder_capability *cap = arg;
272 cap->flags = VIDEO_DECODER_PAL |
273 VIDEO_DECODER_NTSC |
274 VIDEO_DECODER_AUTO |
275 VIDEO_DECODER_CCIR;
276 cap->inputs = 8;
277 cap->outputs = 1;
279 break;
281 case DECODER_GET_STATUS:
283 int *iarg = arg;
284 int status;
285 int res;
287 status = bt819_read(client, 0x00);
288 res = 0;
289 if ((status & 0x80)) {
290 res |= DECODER_STATUS_GOOD;
292 switch (decoder->norm) {
293 case VIDEO_MODE_NTSC:
294 res |= DECODER_STATUS_NTSC;
295 break;
296 case VIDEO_MODE_PAL:
297 res |= DECODER_STATUS_PAL;
298 break;
299 default:
300 case VIDEO_MODE_AUTO:
301 if ((status & 0x10)) {
302 res |= DECODER_STATUS_PAL;
303 } else {
304 res |= DECODER_STATUS_NTSC;
306 break;
308 res |= DECODER_STATUS_COLOR;
309 *iarg = res;
311 dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
312 *iarg);
314 break;
316 case DECODER_SET_NORM:
318 int *iarg = arg;
319 struct timing *timing = NULL;
321 dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
322 *iarg);
324 switch (*iarg) {
325 case VIDEO_MODE_NTSC:
326 bt819_setbit(client, 0x01, 0, 1);
327 bt819_setbit(client, 0x01, 1, 0);
328 bt819_setbit(client, 0x01, 5, 0);
329 bt819_write(client, 0x18, 0x68);
330 bt819_write(client, 0x19, 0x5d);
331 //bt819_setbit(client, 0x1a, 5, 1);
332 timing = &timing_data[VIDEO_MODE_NTSC];
333 break;
334 case VIDEO_MODE_PAL:
335 bt819_setbit(client, 0x01, 0, 1);
336 bt819_setbit(client, 0x01, 1, 1);
337 bt819_setbit(client, 0x01, 5, 1);
338 bt819_write(client, 0x18, 0x7f);
339 bt819_write(client, 0x19, 0x72);
340 //bt819_setbit(client, 0x1a, 5, 0);
341 timing = &timing_data[VIDEO_MODE_PAL];
342 break;
343 case VIDEO_MODE_AUTO:
344 bt819_setbit(client, 0x01, 0, 0);
345 bt819_setbit(client, 0x01, 1, 0);
346 break;
347 default:
348 dprintk(1,
349 KERN_ERR
350 "%s: unsupported norm %d\n",
351 I2C_NAME(client), *iarg);
352 return -EINVAL;
355 if (timing) {
356 bt819_write(client, 0x03,
357 (((timing->vdelay >> 8) & 0x03) << 6) |
358 (((timing->vactive >> 8) & 0x03) << 4) |
359 (((timing->hdelay >> 8) & 0x03) << 2) |
360 ((timing->hactive >> 8) & 0x03) );
361 bt819_write(client, 0x04, timing->vdelay & 0xff);
362 bt819_write(client, 0x05, timing->vactive & 0xff);
363 bt819_write(client, 0x06, timing->hdelay & 0xff);
364 bt819_write(client, 0x07, timing->hactive & 0xff);
365 bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
366 bt819_write(client, 0x09, timing->hscale & 0xff);
369 decoder->norm = *iarg;
371 break;
373 case DECODER_SET_INPUT:
375 int *iarg = arg;
377 dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
378 *iarg);
380 if (*iarg < 0 || *iarg > 7) {
381 return -EINVAL;
384 if (decoder->input != *iarg) {
385 decoder->input = *iarg;
386 /* select mode */
387 if (decoder->input == 0) {
388 bt819_setbit(client, 0x0b, 6, 0);
389 bt819_setbit(client, 0x1a, 1, 1);
390 } else {
391 bt819_setbit(client, 0x0b, 6, 1);
392 bt819_setbit(client, 0x1a, 1, 0);
396 break;
398 case DECODER_SET_OUTPUT:
400 int *iarg = arg;
402 dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
403 *iarg);
405 /* not much choice of outputs */
406 if (*iarg != 0) {
407 return -EINVAL;
410 break;
412 case DECODER_ENABLE_OUTPUT:
414 int *iarg = arg;
415 int enable = (*iarg != 0);
417 dprintk(1, KERN_INFO "%s: enable output %x\n",
418 I2C_NAME(client), *iarg);
420 if (decoder->enable != enable) {
421 decoder->enable = enable;
423 if (decoder->enable) {
424 bt819_setbit(client, 0x16, 7, 0);
425 } else {
426 bt819_setbit(client, 0x16, 7, 1);
430 break;
432 case DECODER_SET_PICTURE:
434 struct video_picture *pic = arg;
436 dprintk(1,
437 KERN_INFO
438 "%s: set picture brightness %d contrast %d colour %d\n",
439 I2C_NAME(client), pic->brightness, pic->contrast,
440 pic->colour);
443 if (decoder->bright != pic->brightness) {
444 /* We want -128 to 127 we get 0-65535 */
445 decoder->bright = pic->brightness;
446 bt819_write(client, 0x0a,
447 (decoder->bright >> 8) - 128);
450 if (decoder->contrast != pic->contrast) {
451 /* We want 0 to 511 we get 0-65535 */
452 decoder->contrast = pic->contrast;
453 bt819_write(client, 0x0c,
454 (decoder->contrast >> 7) & 0xff);
455 bt819_setbit(client, 0x0b, 2,
456 ((decoder->contrast >> 15) & 0x01));
459 if (decoder->sat != pic->colour) {
460 /* We want 0 to 511 we get 0-65535 */
461 decoder->sat = pic->colour;
462 bt819_write(client, 0x0d,
463 (decoder->sat >> 7) & 0xff);
464 bt819_setbit(client, 0x0b, 1,
465 ((decoder->sat >> 15) & 0x01));
467 temp = (decoder->sat * 201) / 237;
468 bt819_write(client, 0x0e, (temp >> 7) & 0xff);
469 bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
472 if (decoder->hue != pic->hue) {
473 /* We want -128 to 127 we get 0-65535 */
474 decoder->hue = pic->hue;
475 bt819_write(client, 0x0f,
476 128 - (decoder->hue >> 8));
479 break;
481 default:
482 return -EINVAL;
485 return 0;
488 /* ----------------------------------------------------------------------- */
491 * Generic i2c probe
492 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
494 static unsigned short normal_i2c[] = {
495 I2C_BT819 >> 1,
496 I2C_CLIENT_END,
499 static unsigned short ignore = I2C_CLIENT_END;
501 static struct i2c_client_address_data addr_data = {
502 .normal_i2c = normal_i2c,
503 .probe = &ignore,
504 .ignore = &ignore,
507 static struct i2c_driver i2c_driver_bt819;
509 static int
510 bt819_detect_client (struct i2c_adapter *adapter,
511 int address,
512 int kind)
514 int i, id;
515 struct bt819 *decoder;
516 struct i2c_client *client;
518 dprintk(1,
519 KERN_INFO
520 "saa7111.c: detecting bt819 client on address 0x%x\n",
521 address << 1);
523 /* Check if the adapter supports the needed features */
524 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
525 return 0;
527 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
528 if (client == 0)
529 return -ENOMEM;
530 client->addr = address;
531 client->adapter = adapter;
532 client->driver = &i2c_driver_bt819;
534 decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
535 if (decoder == NULL) {
536 kfree(client);
537 return -ENOMEM;
539 decoder->norm = VIDEO_MODE_NTSC;
540 decoder->input = 0;
541 decoder->enable = 1;
542 decoder->bright = 32768;
543 decoder->contrast = 32768;
544 decoder->hue = 32768;
545 decoder->sat = 32768;
546 decoder->initialized = 0;
547 i2c_set_clientdata(client, decoder);
549 id = bt819_read(client, 0x17);
550 switch (id & 0xf0) {
551 case 0x70:
552 strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
553 break;
554 case 0x60:
555 strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
556 break;
557 case 0x20:
558 strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
559 break;
560 default:
561 dprintk(1,
562 KERN_ERR
563 "bt819: unknown chip version 0x%x (ver 0x%x)\n",
564 id & 0xf0, id & 0x0f);
565 kfree(decoder);
566 kfree(client);
567 return 0;
570 i = i2c_attach_client(client);
571 if (i) {
572 kfree(client);
573 kfree(decoder);
574 return i;
577 i = bt819_init(client);
578 if (i < 0) {
579 dprintk(1, KERN_ERR "%s_attach: init status %d\n",
580 I2C_NAME(client), i);
581 } else {
582 dprintk(1,
583 KERN_INFO
584 "%s_attach: chip version 0x%x at address 0x%x\n",
585 I2C_NAME(client), id & 0x0f,
586 client->addr << 1);
589 return 0;
592 static int
593 bt819_attach_adapter (struct i2c_adapter *adapter)
595 return i2c_probe(adapter, &addr_data, &bt819_detect_client);
598 static int
599 bt819_detach_client (struct i2c_client *client)
601 struct bt819 *decoder = i2c_get_clientdata(client);
602 int err;
604 err = i2c_detach_client(client);
605 if (err) {
606 return err;
609 kfree(decoder);
610 kfree(client);
612 return 0;
615 /* ----------------------------------------------------------------------- */
617 static struct i2c_driver i2c_driver_bt819 = {
618 .driver = {
619 .name = "bt819",
622 .id = I2C_DRIVERID_BT819,
624 .attach_adapter = bt819_attach_adapter,
625 .detach_client = bt819_detach_client,
626 .command = bt819_command,
629 static int __init
630 bt819_init_module (void)
632 return i2c_add_driver(&i2c_driver_bt819);
635 static void __exit
636 bt819_exit (void)
638 i2c_del_driver(&i2c_driver_bt819);
641 module_init(bt819_init_module);
642 module_exit(bt819_exit);