allow coexistance of N build and AC build.
[tomato.git] / release / src-rt-6.x / linux / linux-2.6 / drivers / media / video / bt819.c
blob59a43603b5cbdcb8f933e28eac5b3454486f0697
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/signal.h>
41 #include <asm/io.h>
42 #include <asm/pgtable.h>
43 #include <asm/page.h>
44 #include <linux/types.h>
46 #include <linux/videodev.h>
47 #include <asm/uaccess.h>
49 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
50 MODULE_AUTHOR("Mike Bernson & Dave Perks");
51 MODULE_LICENSE("GPL");
53 #include <linux/i2c.h>
55 #define I2C_NAME(s) (s)->name
57 #include <linux/video_decoder.h>
59 static int debug = 0;
60 module_param(debug, int, 0);
61 MODULE_PARM_DESC(debug, "Debug level (0-1)");
63 #define dprintk(num, format, args...) \
64 do { \
65 if (debug >= num) \
66 printk(format, ##args); \
67 } while (0)
69 /* ----------------------------------------------------------------------- */
71 struct bt819 {
72 unsigned char reg[32];
74 int initialized;
75 int norm;
76 int input;
77 int enable;
78 int bright;
79 int contrast;
80 int hue;
81 int sat;
84 struct timing {
85 int hactive;
86 int hdelay;
87 int vactive;
88 int vdelay;
89 int hscale;
90 int vscale;
93 /* for values, see the bt819 datasheet */
94 static struct timing timing_data[] = {
95 {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
96 {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
99 #define I2C_BT819 0x8a
101 /* ----------------------------------------------------------------------- */
103 static inline int
104 bt819_write (struct i2c_client *client,
105 u8 reg,
106 u8 value)
108 struct bt819 *decoder = i2c_get_clientdata(client);
110 decoder->reg[reg] = value;
111 return i2c_smbus_write_byte_data(client, reg, value);
114 static inline int
115 bt819_setbit (struct i2c_client *client,
116 u8 reg,
117 u8 bit,
118 u8 value)
120 struct bt819 *decoder = i2c_get_clientdata(client);
122 return bt819_write(client, reg,
123 (decoder->
124 reg[reg] & ~(1 << bit)) |
125 (value ? (1 << bit) : 0));
128 static int
129 bt819_write_block (struct i2c_client *client,
130 const u8 *data,
131 unsigned int len)
133 int ret = -1;
134 u8 reg;
136 /* the bt819 has an autoincrement function, use it if
137 * the adapter understands raw I2C */
138 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
139 /* do raw I2C, not smbus compatible */
140 struct bt819 *decoder = i2c_get_clientdata(client);
141 u8 block_data[32];
142 int block_len;
144 while (len >= 2) {
145 block_len = 0;
146 block_data[block_len++] = reg = data[0];
147 do {
148 block_data[block_len++] =
149 decoder->reg[reg++] = data[1];
150 len -= 2;
151 data += 2;
152 } while (len >= 2 && data[0] == reg &&
153 block_len < 32);
154 if ((ret = i2c_master_send(client, block_data,
155 block_len)) < 0)
156 break;
158 } else {
159 /* do some slow I2C emulation kind of thing */
160 while (len >= 2) {
161 reg = *data++;
162 if ((ret = bt819_write(client, reg, *data++)) < 0)
163 break;
164 len -= 2;
168 return ret;
171 static inline int
172 bt819_read (struct i2c_client *client,
173 u8 reg)
175 return i2c_smbus_read_byte_data(client, reg);
178 static int
179 bt819_init (struct i2c_client *client)
181 struct bt819 *decoder = i2c_get_clientdata(client);
183 static unsigned char init[] = {
184 //0x1f, 0x00, /* Reset */
185 0x01, 0x59, /* 0x01 input format */
186 0x02, 0x00, /* 0x02 temporal decimation */
187 0x03, 0x12, /* 0x03 Cropping msb */
188 0x04, 0x16, /* 0x04 Vertical Delay, lsb */
189 0x05, 0xe0, /* 0x05 Vertical Active lsb */
190 0x06, 0x80, /* 0x06 Horizontal Delay lsb */
191 0x07, 0xd0, /* 0x07 Horizontal Active lsb */
192 0x08, 0x00, /* 0x08 Horizontal Scaling msb */
193 0x09, 0xf8, /* 0x09 Horizontal Scaling lsb */
194 0x0a, 0x00, /* 0x0a Brightness control */
195 0x0b, 0x30, /* 0x0b Miscellaneous control */
196 0x0c, 0xd8, /* 0x0c Luma Gain lsb */
197 0x0d, 0xfe, /* 0x0d Chroma Gain (U) lsb */
198 0x0e, 0xb4, /* 0x0e Chroma Gain (V) msb */
199 0x0f, 0x00, /* 0x0f Hue control */
200 0x12, 0x04, /* 0x12 Output Format */
201 0x13, 0x20, /* 0x13 Vertial Scaling msb 0x00
202 chroma comb OFF, line drop scaling, interlace scaling
203 BUG? Why does turning the chroma comb on fuck up color?
204 Bug in the bt819 stepping on my board?
206 0x14, 0x00, /* 0x14 Vertial Scaling lsb */
207 0x16, 0x07, /* 0x16 Video Timing Polarity
208 ACTIVE=active low
209 FIELD: high=odd,
210 vreset=active high,
211 hreset=active high */
212 0x18, 0x68, /* 0x18 AGC Delay */
213 0x19, 0x5d, /* 0x19 Burst Gate Delay */
214 0x1a, 0x80, /* 0x1a ADC Interface */
217 struct timing *timing = &timing_data[decoder->norm];
219 init[0x03 * 2 - 1] =
220 (((timing->vdelay >> 8) & 0x03) << 6) | (((timing->
221 vactive >> 8) &
222 0x03) << 4) |
223 (((timing->hdelay >> 8) & 0x03) << 2) | ((timing->
224 hactive >> 8) &
225 0x03);
226 init[0x04 * 2 - 1] = timing->vdelay & 0xff;
227 init[0x05 * 2 - 1] = timing->vactive & 0xff;
228 init[0x06 * 2 - 1] = timing->hdelay & 0xff;
229 init[0x07 * 2 - 1] = timing->hactive & 0xff;
230 init[0x08 * 2 - 1] = timing->hscale >> 8;
231 init[0x09 * 2 - 1] = timing->hscale & 0xff;
232 /* 0x15 in array is address 0x19 */
233 init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93; /* Chroma burst delay */
234 /* reset */
235 bt819_write(client, 0x1f, 0x00);
236 mdelay(1);
238 /* init */
239 return bt819_write_block(client, init, sizeof(init));
243 /* ----------------------------------------------------------------------- */
245 static int
246 bt819_command (struct i2c_client *client,
247 unsigned int cmd,
248 void *arg)
250 int temp;
252 struct bt819 *decoder = i2c_get_clientdata(client);
254 if (!decoder->initialized) { // First call to bt819_init could be
255 bt819_init(client); // without #FRST = 0
256 decoder->initialized = 1;
259 switch (cmd) {
261 case 0:
262 /* This is just for testing!!! */
263 bt819_init(client);
264 break;
266 case DECODER_GET_CAPABILITIES:
268 struct video_decoder_capability *cap = arg;
270 cap->flags = VIDEO_DECODER_PAL |
271 VIDEO_DECODER_NTSC |
272 VIDEO_DECODER_AUTO |
273 VIDEO_DECODER_CCIR;
274 cap->inputs = 8;
275 cap->outputs = 1;
277 break;
279 case DECODER_GET_STATUS:
281 int *iarg = arg;
282 int status;
283 int res;
285 status = bt819_read(client, 0x00);
286 res = 0;
287 if ((status & 0x80)) {
288 res |= DECODER_STATUS_GOOD;
290 switch (decoder->norm) {
291 case VIDEO_MODE_NTSC:
292 res |= DECODER_STATUS_NTSC;
293 break;
294 case VIDEO_MODE_PAL:
295 res |= DECODER_STATUS_PAL;
296 break;
297 default:
298 case VIDEO_MODE_AUTO:
299 if ((status & 0x10)) {
300 res |= DECODER_STATUS_PAL;
301 } else {
302 res |= DECODER_STATUS_NTSC;
304 break;
306 res |= DECODER_STATUS_COLOR;
307 *iarg = res;
309 dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
310 *iarg);
312 break;
314 case DECODER_SET_NORM:
316 int *iarg = arg;
317 struct timing *timing = NULL;
319 dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
320 *iarg);
322 switch (*iarg) {
323 case VIDEO_MODE_NTSC:
324 bt819_setbit(client, 0x01, 0, 1);
325 bt819_setbit(client, 0x01, 1, 0);
326 bt819_setbit(client, 0x01, 5, 0);
327 bt819_write(client, 0x18, 0x68);
328 bt819_write(client, 0x19, 0x5d);
329 //bt819_setbit(client, 0x1a, 5, 1);
330 timing = &timing_data[VIDEO_MODE_NTSC];
331 break;
332 case VIDEO_MODE_PAL:
333 bt819_setbit(client, 0x01, 0, 1);
334 bt819_setbit(client, 0x01, 1, 1);
335 bt819_setbit(client, 0x01, 5, 1);
336 bt819_write(client, 0x18, 0x7f);
337 bt819_write(client, 0x19, 0x72);
338 //bt819_setbit(client, 0x1a, 5, 0);
339 timing = &timing_data[VIDEO_MODE_PAL];
340 break;
341 case VIDEO_MODE_AUTO:
342 bt819_setbit(client, 0x01, 0, 0);
343 bt819_setbit(client, 0x01, 1, 0);
344 break;
345 default:
346 dprintk(1,
347 KERN_ERR
348 "%s: unsupported norm %d\n",
349 I2C_NAME(client), *iarg);
350 return -EINVAL;
353 if (timing) {
354 bt819_write(client, 0x03,
355 (((timing->vdelay >> 8) & 0x03) << 6) |
356 (((timing->vactive >> 8) & 0x03) << 4) |
357 (((timing->hdelay >> 8) & 0x03) << 2) |
358 ((timing->hactive >> 8) & 0x03) );
359 bt819_write(client, 0x04, timing->vdelay & 0xff);
360 bt819_write(client, 0x05, timing->vactive & 0xff);
361 bt819_write(client, 0x06, timing->hdelay & 0xff);
362 bt819_write(client, 0x07, timing->hactive & 0xff);
363 bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
364 bt819_write(client, 0x09, timing->hscale & 0xff);
367 decoder->norm = *iarg;
369 break;
371 case DECODER_SET_INPUT:
373 int *iarg = arg;
375 dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
376 *iarg);
378 if (*iarg < 0 || *iarg > 7) {
379 return -EINVAL;
382 if (decoder->input != *iarg) {
383 decoder->input = *iarg;
384 /* select mode */
385 if (decoder->input == 0) {
386 bt819_setbit(client, 0x0b, 6, 0);
387 bt819_setbit(client, 0x1a, 1, 1);
388 } else {
389 bt819_setbit(client, 0x0b, 6, 1);
390 bt819_setbit(client, 0x1a, 1, 0);
394 break;
396 case DECODER_SET_OUTPUT:
398 int *iarg = arg;
400 dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
401 *iarg);
403 /* not much choice of outputs */
404 if (*iarg != 0) {
405 return -EINVAL;
408 break;
410 case DECODER_ENABLE_OUTPUT:
412 int *iarg = arg;
413 int enable = (*iarg != 0);
415 dprintk(1, KERN_INFO "%s: enable output %x\n",
416 I2C_NAME(client), *iarg);
418 if (decoder->enable != enable) {
419 decoder->enable = enable;
421 if (decoder->enable) {
422 bt819_setbit(client, 0x16, 7, 0);
423 } else {
424 bt819_setbit(client, 0x16, 7, 1);
428 break;
430 case DECODER_SET_PICTURE:
432 struct video_picture *pic = arg;
434 dprintk(1,
435 KERN_INFO
436 "%s: set picture brightness %d contrast %d colour %d\n",
437 I2C_NAME(client), pic->brightness, pic->contrast,
438 pic->colour);
441 if (decoder->bright != pic->brightness) {
442 /* We want -128 to 127 we get 0-65535 */
443 decoder->bright = pic->brightness;
444 bt819_write(client, 0x0a,
445 (decoder->bright >> 8) - 128);
448 if (decoder->contrast != pic->contrast) {
449 /* We want 0 to 511 we get 0-65535 */
450 decoder->contrast = pic->contrast;
451 bt819_write(client, 0x0c,
452 (decoder->contrast >> 7) & 0xff);
453 bt819_setbit(client, 0x0b, 2,
454 ((decoder->contrast >> 15) & 0x01));
457 if (decoder->sat != pic->colour) {
458 /* We want 0 to 511 we get 0-65535 */
459 decoder->sat = pic->colour;
460 bt819_write(client, 0x0d,
461 (decoder->sat >> 7) & 0xff);
462 bt819_setbit(client, 0x0b, 1,
463 ((decoder->sat >> 15) & 0x01));
465 temp = (decoder->sat * 201) / 237;
466 bt819_write(client, 0x0e, (temp >> 7) & 0xff);
467 bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
470 if (decoder->hue != pic->hue) {
471 /* We want -128 to 127 we get 0-65535 */
472 decoder->hue = pic->hue;
473 bt819_write(client, 0x0f,
474 128 - (decoder->hue >> 8));
477 break;
479 default:
480 return -EINVAL;
483 return 0;
486 /* ----------------------------------------------------------------------- */
489 * Generic i2c probe
490 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
492 static unsigned short normal_i2c[] = {
493 I2C_BT819 >> 1,
494 I2C_CLIENT_END,
497 static unsigned short ignore = I2C_CLIENT_END;
499 static struct i2c_client_address_data addr_data = {
500 .normal_i2c = normal_i2c,
501 .probe = &ignore,
502 .ignore = &ignore,
505 static struct i2c_driver i2c_driver_bt819;
507 static int
508 bt819_detect_client (struct i2c_adapter *adapter,
509 int address,
510 int kind)
512 int i, id;
513 struct bt819 *decoder;
514 struct i2c_client *client;
516 dprintk(1,
517 KERN_INFO
518 "saa7111.c: detecting bt819 client on address 0x%x\n",
519 address << 1);
521 /* Check if the adapter supports the needed features */
522 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
523 return 0;
525 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
526 if (client == 0)
527 return -ENOMEM;
528 client->addr = address;
529 client->adapter = adapter;
530 client->driver = &i2c_driver_bt819;
532 decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
533 if (decoder == NULL) {
534 kfree(client);
535 return -ENOMEM;
537 decoder->norm = VIDEO_MODE_NTSC;
538 decoder->input = 0;
539 decoder->enable = 1;
540 decoder->bright = 32768;
541 decoder->contrast = 32768;
542 decoder->hue = 32768;
543 decoder->sat = 32768;
544 decoder->initialized = 0;
545 i2c_set_clientdata(client, decoder);
547 id = bt819_read(client, 0x17);
548 switch (id & 0xf0) {
549 case 0x70:
550 strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
551 break;
552 case 0x60:
553 strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
554 break;
555 case 0x20:
556 strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
557 break;
558 default:
559 dprintk(1,
560 KERN_ERR
561 "bt819: unknown chip version 0x%x (ver 0x%x)\n",
562 id & 0xf0, id & 0x0f);
563 kfree(decoder);
564 kfree(client);
565 return 0;
568 i = i2c_attach_client(client);
569 if (i) {
570 kfree(client);
571 kfree(decoder);
572 return i;
575 i = bt819_init(client);
576 if (i < 0) {
577 dprintk(1, KERN_ERR "%s_attach: init status %d\n",
578 I2C_NAME(client), i);
579 } else {
580 dprintk(1,
581 KERN_INFO
582 "%s_attach: chip version 0x%x at address 0x%x\n",
583 I2C_NAME(client), id & 0x0f,
584 client->addr << 1);
587 return 0;
590 static int
591 bt819_attach_adapter (struct i2c_adapter *adapter)
593 return i2c_probe(adapter, &addr_data, &bt819_detect_client);
596 static int
597 bt819_detach_client (struct i2c_client *client)
599 struct bt819 *decoder = i2c_get_clientdata(client);
600 int err;
602 err = i2c_detach_client(client);
603 if (err) {
604 return err;
607 kfree(decoder);
608 kfree(client);
610 return 0;
613 /* ----------------------------------------------------------------------- */
615 static struct i2c_driver i2c_driver_bt819 = {
616 .driver = {
617 .name = "bt819",
620 .id = I2C_DRIVERID_BT819,
622 .attach_adapter = bt819_attach_adapter,
623 .detach_client = bt819_detach_client,
624 .command = bt819_command,
627 static int __init
628 bt819_init_module (void)
630 return i2c_add_driver(&i2c_driver_bt819);
633 static void __exit
634 bt819_exit (void)
636 i2c_del_driver(&i2c_driver_bt819);
639 module_init(bt819_init_module);
640 module_exit(bt819_exit);