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>
42 #include <asm/pgtable.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>
60 module_param(debug
, int, 0);
61 MODULE_PARM_DESC(debug
, "Debug level (0-1)");
63 #define dprintk(num, format, args...) \
66 printk(format, ##args); \
69 /* ----------------------------------------------------------------------- */
72 unsigned char reg
[32];
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 /* ----------------------------------------------------------------------- */
104 bt819_write (struct i2c_client
*client
,
108 struct bt819
*decoder
= i2c_get_clientdata(client
);
110 decoder
->reg
[reg
] = value
;
111 return i2c_smbus_write_byte_data(client
, reg
, value
);
115 bt819_setbit (struct i2c_client
*client
,
120 struct bt819
*decoder
= i2c_get_clientdata(client
);
122 return bt819_write(client
, reg
,
124 reg
[reg
] & ~(1 << bit
)) |
125 (value
? (1 << bit
) : 0));
129 bt819_write_block (struct i2c_client
*client
,
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
);
146 block_data
[block_len
++] = reg
= data
[0];
148 block_data
[block_len
++] =
149 decoder
->reg
[reg
++] = data
[1];
152 } while (len
>= 2 && data
[0] == reg
&&
154 if ((ret
= i2c_master_send(client
, block_data
,
159 /* do some slow I2C emulation kind of thing */
162 if ((ret
= bt819_write(client
, reg
, *data
++)) < 0)
172 bt819_read (struct i2c_client
*client
,
175 return i2c_smbus_read_byte_data(client
, reg
);
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
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
];
220 (((timing
->vdelay
>> 8) & 0x03) << 6) | (((timing
->
223 (((timing
->hdelay
>> 8) & 0x03) << 2) | ((timing
->
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 */
235 bt819_write(client
, 0x1f, 0x00);
239 return bt819_write_block(client
, init
, sizeof(init
));
243 /* ----------------------------------------------------------------------- */
246 bt819_command (struct i2c_client
*client
,
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;
262 /* This is just for testing!!! */
266 case DECODER_GET_CAPABILITIES
:
268 struct video_decoder_capability
*cap
= arg
;
270 cap
->flags
= VIDEO_DECODER_PAL
|
279 case DECODER_GET_STATUS
:
285 status
= bt819_read(client
, 0x00);
287 if ((status
& 0x80)) {
288 res
|= DECODER_STATUS_GOOD
;
290 switch (decoder
->norm
) {
291 case VIDEO_MODE_NTSC
:
292 res
|= DECODER_STATUS_NTSC
;
295 res
|= DECODER_STATUS_PAL
;
298 case VIDEO_MODE_AUTO
:
299 if ((status
& 0x10)) {
300 res
|= DECODER_STATUS_PAL
;
302 res
|= DECODER_STATUS_NTSC
;
306 res
|= DECODER_STATUS_COLOR
;
309 dprintk(1, KERN_INFO
"%s: get status %x\n", I2C_NAME(client
),
314 case DECODER_SET_NORM
:
317 struct timing
*timing
= NULL
;
319 dprintk(1, KERN_INFO
"%s: set norm %x\n", I2C_NAME(client
),
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
];
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
];
341 case VIDEO_MODE_AUTO
:
342 bt819_setbit(client
, 0x01, 0, 0);
343 bt819_setbit(client
, 0x01, 1, 0);
348 "%s: unsupported norm %d\n",
349 I2C_NAME(client
), *iarg
);
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
;
371 case DECODER_SET_INPUT
:
375 dprintk(1, KERN_INFO
"%s: set input %x\n", I2C_NAME(client
),
378 if (*iarg
< 0 || *iarg
> 7) {
382 if (decoder
->input
!= *iarg
) {
383 decoder
->input
= *iarg
;
385 if (decoder
->input
== 0) {
386 bt819_setbit(client
, 0x0b, 6, 0);
387 bt819_setbit(client
, 0x1a, 1, 1);
389 bt819_setbit(client
, 0x0b, 6, 1);
390 bt819_setbit(client
, 0x1a, 1, 0);
396 case DECODER_SET_OUTPUT
:
400 dprintk(1, KERN_INFO
"%s: set output %x\n", I2C_NAME(client
),
403 /* not much choice of outputs */
410 case DECODER_ENABLE_OUTPUT
:
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);
424 bt819_setbit(client
, 0x16, 7, 1);
430 case DECODER_SET_PICTURE
:
432 struct video_picture
*pic
= arg
;
436 "%s: set picture brightness %d contrast %d colour %d\n",
437 I2C_NAME(client
), pic
->brightness
, pic
->contrast
,
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));
486 /* ----------------------------------------------------------------------- */
490 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
492 static unsigned short normal_i2c
[] = {
497 static unsigned short ignore
= I2C_CLIENT_END
;
499 static struct i2c_client_address_data addr_data
= {
500 .normal_i2c
= normal_i2c
,
505 static struct i2c_driver i2c_driver_bt819
;
508 bt819_detect_client (struct i2c_adapter
*adapter
,
513 struct bt819
*decoder
;
514 struct i2c_client
*client
;
518 "saa7111.c: detecting bt819 client on address 0x%x\n",
521 /* Check if the adapter supports the needed features */
522 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_BYTE_DATA
))
525 client
= kzalloc(sizeof(struct i2c_client
), GFP_KERNEL
);
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
) {
537 decoder
->norm
= VIDEO_MODE_NTSC
;
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);
550 strlcpy(I2C_NAME(client
), "bt819a", sizeof(I2C_NAME(client
)));
553 strlcpy(I2C_NAME(client
), "bt817a", sizeof(I2C_NAME(client
)));
556 strlcpy(I2C_NAME(client
), "bt815a", sizeof(I2C_NAME(client
)));
561 "bt819: unknown chip version 0x%x (ver 0x%x)\n",
562 id
& 0xf0, id
& 0x0f);
568 i
= i2c_attach_client(client
);
575 i
= bt819_init(client
);
577 dprintk(1, KERN_ERR
"%s_attach: init status %d\n",
578 I2C_NAME(client
), i
);
582 "%s_attach: chip version 0x%x at address 0x%x\n",
583 I2C_NAME(client
), id
& 0x0f,
591 bt819_attach_adapter (struct i2c_adapter
*adapter
)
593 return i2c_probe(adapter
, &addr_data
, &bt819_detect_client
);
597 bt819_detach_client (struct i2c_client
*client
)
599 struct bt819
*decoder
= i2c_get_clientdata(client
);
602 err
= i2c_detach_client(client
);
613 /* ----------------------------------------------------------------------- */
615 static struct i2c_driver i2c_driver_bt819
= {
620 .id
= I2C_DRIVERID_BT819
,
622 .attach_adapter
= bt819_attach_adapter
,
623 .detach_client
= bt819_detach_client
,
624 .command
= bt819_command
,
628 bt819_init_module (void)
630 return i2c_add_driver(&i2c_driver_bt819
);
636 i2c_del_driver(&i2c_driver_bt819
);
639 module_init(bt819_init_module
);
640 module_exit(bt819_exit
);