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
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>
36 #include <linux/kernel.h>
37 #include <linux/major.h>
38 #include <linux/slab.h>
40 #include <linux/signal.h>
41 #include <linux/types.h>
42 #include <linux/i2c.h>
44 #include <asm/pgtable.h>
46 #include <asm/uaccess.h>
48 #include <linux/videodev.h>
49 #include <linux/video_decoder.h>
52 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
53 MODULE_AUTHOR("Mike Bernson & Dave Perks");
54 MODULE_LICENSE("GPL");
57 #define I2C_NAME(s) (s)->name
61 module_param(debug, int, 0);
62 MODULE_PARM_DESC(debug, "Debug level (0-1)");
64 #define dprintk(num, format, args...) \
67 printk(format, ##args); \
70 /* ----------------------------------------------------------------------- */
73 unsigned char reg[32];
94 /* for values, see the bt819 datasheet */
95 static struct timing timing_data[] = {
96 {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
97 {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
100 #define I2C_BT819 0x8a
102 /* ----------------------------------------------------------------------- */
105 bt819_write (struct i2c_client *client,
109 struct bt819 *decoder = i2c_get_clientdata(client);
111 decoder->reg[reg] = value;
112 return i2c_smbus_write_byte_data(client, reg, value);
116 bt819_setbit (struct i2c_client *client,
121 struct bt819 *decoder = i2c_get_clientdata(client);
123 return bt819_write(client, reg,
125 reg[reg] & ~(1 << bit)) |
126 (value ? (1 << bit) : 0));
130 bt819_write_block (struct i2c_client *client,
137 /* the bt819 has an autoincrement function, use it if
138 * the adapter understands raw I2C */
139 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
140 /* do raw I2C, not smbus compatible */
141 struct bt819 *decoder = i2c_get_clientdata(client);
147 block_data[block_len++] = reg = data[0];
149 block_data[block_len++] =
150 decoder->reg[reg++] = data[1];
153 } while (len >= 2 && data[0] == reg &&
155 if ((ret = i2c_master_send(client, block_data,
160 /* do some slow I2C emulation kind of thing */
163 if ((ret = bt819_write(client, reg, *data++)) < 0)
173 bt819_read (struct i2c_client *client,
176 return i2c_smbus_read_byte_data(client, reg);
180 bt819_init (struct i2c_client *client)
182 struct bt819 *decoder = i2c_get_clientdata(client);
184 static unsigned char init[] = {
185 //0x1f, 0x00, /* Reset */
186 0x01, 0x59, /* 0x01 input format */
187 0x02, 0x00, /* 0x02 temporal decimation */
188 0x03, 0x12, /* 0x03 Cropping msb */
189 0x04, 0x16, /* 0x04 Vertical Delay, lsb */
190 0x05, 0xe0, /* 0x05 Vertical Active lsb */
191 0x06, 0x80, /* 0x06 Horizontal Delay lsb */
192 0x07, 0xd0, /* 0x07 Horizontal Active lsb */
193 0x08, 0x00, /* 0x08 Horizontal Scaling msb */
194 0x09, 0xf8, /* 0x09 Horizontal Scaling lsb */
195 0x0a, 0x00, /* 0x0a Brightness control */
196 0x0b, 0x30, /* 0x0b Miscellaneous control */
197 0x0c, 0xd8, /* 0x0c Luma Gain lsb */
198 0x0d, 0xfe, /* 0x0d Chroma Gain (U) lsb */
199 0x0e, 0xb4, /* 0x0e Chroma Gain (V) msb */
200 0x0f, 0x00, /* 0x0f Hue control */
201 0x12, 0x04, /* 0x12 Output Format */
202 0x13, 0x20, /* 0x13 Vertial Scaling msb 0x00
203 chroma comb OFF, line drop scaling, interlace scaling
204 BUG? Why does turning the chroma comb on fuck up color?
205 Bug in the bt819 stepping on my board?
207 0x14, 0x00, /* 0x14 Vertial Scaling lsb */
208 0x16, 0x07, /* 0x16 Video Timing Polarity
212 hreset=active high */
213 0x18, 0x68, /* 0x18 AGC Delay */
214 0x19, 0x5d, /* 0x19 Burst Gate Delay */
215 0x1a, 0x80, /* 0x1a ADC Interface */
218 struct timing *timing = &timing_data[decoder->norm];
221 (((timing->vdelay >> 8) & 0x03) << 6) | (((timing->
224 (((timing->hdelay >> 8) & 0x03) << 2) | ((timing->
227 init[0x04 * 2 - 1] = timing->vdelay & 0xff;
228 init[0x05 * 2 - 1] = timing->vactive & 0xff;
229 init[0x06 * 2 - 1] = timing->hdelay & 0xff;
230 init[0x07 * 2 - 1] = timing->hactive & 0xff;
231 init[0x08 * 2 - 1] = timing->hscale >> 8;
232 init[0x09 * 2 - 1] = timing->hscale & 0xff;
233 /* 0x15 in array is address 0x19 */
234 init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93; /* Chroma burst delay */
236 bt819_write(client, 0x1f, 0x00);
240 return bt819_write_block(client, init, sizeof(init));
244 /* ----------------------------------------------------------------------- */
247 bt819_command (struct i2c_client *client,
253 struct bt819 *decoder = i2c_get_clientdata(client);
255 if (!decoder->initialized) { // First call to bt819_init could be
256 bt819_init(client); // without #FRST = 0
257 decoder->initialized = 1;
263 /* This is just for testing!!! */
267 case DECODER_GET_CAPABILITIES:
269 struct video_decoder_capability *cap = arg;
271 cap->flags = VIDEO_DECODER_PAL |
280 case DECODER_GET_STATUS:
286 status = bt819_read(client, 0x00);
288 if ((status & 0x80)) {
289 res |= DECODER_STATUS_GOOD;
291 switch (decoder->norm) {
292 case VIDEO_MODE_NTSC:
293 res |= DECODER_STATUS_NTSC;
296 res |= DECODER_STATUS_PAL;
299 case VIDEO_MODE_AUTO:
300 if ((status & 0x10)) {
301 res |= DECODER_STATUS_PAL;
303 res |= DECODER_STATUS_NTSC;
307 res |= DECODER_STATUS_COLOR;
310 dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
315 case DECODER_SET_NORM:
318 struct timing *timing = NULL;
320 dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
324 case VIDEO_MODE_NTSC:
325 bt819_setbit(client, 0x01, 0, 1);
326 bt819_setbit(client, 0x01, 1, 0);
327 bt819_setbit(client, 0x01, 5, 0);
328 bt819_write(client, 0x18, 0x68);
329 bt819_write(client, 0x19, 0x5d);
330 //bt819_setbit(client, 0x1a, 5, 1);
331 timing = &timing_data[VIDEO_MODE_NTSC];
334 bt819_setbit(client, 0x01, 0, 1);
335 bt819_setbit(client, 0x01, 1, 1);
336 bt819_setbit(client, 0x01, 5, 1);
337 bt819_write(client, 0x18, 0x7f);
338 bt819_write(client, 0x19, 0x72);
339 //bt819_setbit(client, 0x1a, 5, 0);
340 timing = &timing_data[VIDEO_MODE_PAL];
342 case VIDEO_MODE_AUTO:
343 bt819_setbit(client, 0x01, 0, 0);
344 bt819_setbit(client, 0x01, 1, 0);
349 "%s: unsupported norm %d\n",
350 I2C_NAME(client), *iarg);
355 bt819_write(client, 0x03,
356 (((timing->vdelay >> 8) & 0x03) << 6) |
357 (((timing->vactive >> 8) & 0x03) << 4) |
358 (((timing->hdelay >> 8) & 0x03) << 2) |
359 ((timing->hactive >> 8) & 0x03) );
360 bt819_write(client, 0x04, timing->vdelay & 0xff);
361 bt819_write(client, 0x05, timing->vactive & 0xff);
362 bt819_write(client, 0x06, timing->hdelay & 0xff);
363 bt819_write(client, 0x07, timing->hactive & 0xff);
364 bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
365 bt819_write(client, 0x09, timing->hscale & 0xff);
368 decoder->norm = *iarg;
372 case DECODER_SET_INPUT:
376 dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
379 if (*iarg < 0 || *iarg > 7) {
383 if (decoder->input != *iarg) {
384 decoder->input = *iarg;
386 if (decoder->input == 0) {
387 bt819_setbit(client, 0x0b, 6, 0);
388 bt819_setbit(client, 0x1a, 1, 1);
390 bt819_setbit(client, 0x0b, 6, 1);
391 bt819_setbit(client, 0x1a, 1, 0);
397 case DECODER_SET_OUTPUT:
401 dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
404 /* not much choice of outputs */
411 case DECODER_ENABLE_OUTPUT:
414 int enable = (*iarg != 0);
416 dprintk(1, KERN_INFO "%s: enable output %x\n",
417 I2C_NAME(client), *iarg);
419 if (decoder->enable != enable) {
420 decoder->enable = enable;
422 if (decoder->enable) {
423 bt819_setbit(client, 0x16, 7, 0);
425 bt819_setbit(client, 0x16, 7, 1);
431 case DECODER_SET_PICTURE:
433 struct video_picture *pic = arg;
437 "%s: set picture brightness %d contrast %d colour %d\n",
438 I2C_NAME(client), pic->brightness, pic->contrast,
442 if (decoder->bright != pic->brightness) {
443 /* We want -128 to 127 we get 0-65535 */
444 decoder->bright = pic->brightness;
445 bt819_write(client, 0x0a,
446 (decoder->bright >> 8) - 128);
449 if (decoder->contrast != pic->contrast) {
450 /* We want 0 to 511 we get 0-65535 */
451 decoder->contrast = pic->contrast;
452 bt819_write(client, 0x0c,
453 (decoder->contrast >> 7) & 0xff);
454 bt819_setbit(client, 0x0b, 2,
455 ((decoder->contrast >> 15) & 0x01));
458 if (decoder->sat != pic->colour) {
459 /* We want 0 to 511 we get 0-65535 */
460 decoder->sat = pic->colour;
461 bt819_write(client, 0x0d,
462 (decoder->sat >> 7) & 0xff);
463 bt819_setbit(client, 0x0b, 1,
464 ((decoder->sat >> 15) & 0x01));
466 temp = (decoder->sat * 201) / 237;
467 bt819_write(client, 0x0e, (temp >> 7) & 0xff);
468 bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
471 if (decoder->hue != pic->hue) {
472 /* We want -128 to 127 we get 0-65535 */
473 decoder->hue = pic->hue;
474 bt819_write(client, 0x0f,
475 128 - (decoder->hue >> 8));
487 /* ----------------------------------------------------------------------- */
491 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
493 static unsigned short normal_i2c[] = {
498 static unsigned short ignore = I2C_CLIENT_END;
500 static struct i2c_client_address_data addr_data = {
501 .normal_i2c = normal_i2c,
506 static struct i2c_driver i2c_driver_bt819;
509 bt819_detect_client (struct i2c_adapter *adapter,
514 struct bt819 *decoder;
515 struct i2c_client *client;
519 "bt819: detecting bt819 client on address 0x%x\n",
522 /* Check if the adapter supports the needed features */
523 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
526 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
529 client->addr = address;
530 client->adapter = adapter;
531 client->driver = &i2c_driver_bt819;
533 decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
534 if (decoder == NULL) {
538 decoder->norm = VIDEO_MODE_NTSC;
541 decoder->bright = 32768;
542 decoder->contrast = 32768;
543 decoder->hue = 32768;
544 decoder->sat = 32768;
545 decoder->initialized = 0;
546 i2c_set_clientdata(client, decoder);
548 id = bt819_read(client, 0x17);
551 strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
554 strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
557 strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
562 "bt819: unknown chip version 0x%x (ver 0x%x)\n",
563 id & 0xf0, id & 0x0f);
569 i = i2c_attach_client(client);
576 i = bt819_init(client);
578 dprintk(1, KERN_ERR "%s_attach: init status %d\n",
579 I2C_NAME(client), i);
583 "%s_attach: chip version 0x%x at address 0x%x\n",
584 I2C_NAME(client), id & 0x0f,
592 bt819_attach_adapter (struct i2c_adapter *adapter)
594 return i2c_probe(adapter, &addr_data, &bt819_detect_client);
598 bt819_detach_client (struct i2c_client *client)
600 struct bt819 *decoder = i2c_get_clientdata(client);
603 err = i2c_detach_client(client);
614 /* ----------------------------------------------------------------------- */
616 static struct i2c_driver i2c_driver_bt819 = {
621 .id = I2C_DRIVERID_BT819,
623 .attach_adapter = bt819_attach_adapter,
624 .detach_client = bt819_detach_client,
625 .command = bt819_command,
629 bt819_init_module (void)
631 return i2c_add_driver(&i2c_driver_bt819);
637 i2c_del_driver(&i2c_driver_bt819);
640 module_init(bt819_init_module);
641 module_exit(bt819_exit);