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.
|