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/signal.h> 41#include <asm/io.h> 42#include <asm/pgtable.h> 43#include <asm/page.h> 44#include <linux/types.h> 45 46#include <linux/videodev.h> 47#include <asm/uaccess.h> 48 49MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); 50MODULE_AUTHOR("Mike Bernson & Dave Perks"); 51MODULE_LICENSE("GPL"); 52 53#include <linux/i2c.h> 54 55#define I2C_NAME(s) (s)->name 56 57#include <linux/video_decoder.h> 58 59static int debug = 0; 60module_param(debug, int, 0); 61MODULE_PARM_DESC(debug, "Debug level (0-1)"); 62 63#define dprintk(num, format, args...) \ 64 do { \ 65 if (debug >= num) \ 66 printk(format, ##args); \ 67 } while (0) 68 69/* ----------------------------------------------------------------------- */ 70 71struct bt819 { 72 unsigned char reg[32]; 73 74 int initialized; 75 int norm; 76 int input; 77 int enable; 78 int bright; 79 int contrast; 80 int hue; 81 int sat; 82}; 83 84struct timing { 85 int hactive; 86 int hdelay; 87 int vactive; 88 int vdelay; 89 int hscale; 90 int vscale; 91}; 92 93/* for values, see the bt819 datasheet */ 94static struct timing timing_data[] = { 95 {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000}, 96 {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000}, 97}; 98 99#define I2C_BT819 0x8a 100 101/* ----------------------------------------------------------------------- */ 102 103static inline int 104bt819_write (struct i2c_client *client, 105 u8 reg, 106 u8 value) 107{ 108 struct bt819 *decoder = i2c_get_clientdata(client); 109 110 decoder->reg[reg] = value; 111 return i2c_smbus_write_byte_data(client, reg, value); 112} 113 114static inline int 115bt819_setbit (struct i2c_client *client, 116 u8 reg, 117 u8 bit, 118 u8 value) 119{ 120 struct bt819 *decoder = i2c_get_clientdata(client); 121 122 return bt819_write(client, reg, 123 (decoder-> 124 reg[reg] & ~(1 << bit)) | 125 (value ? (1 << bit) : 0)); 126} 127 128static int 129bt819_write_block (struct i2c_client *client, 130 const u8 *data, 131 unsigned int len) 132{ 133 int ret = -1; 134 u8 reg; 135 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; 143 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; 157 } 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; 165 } 166 } 167 168 return ret; 169} 170 171static inline int 172bt819_read (struct i2c_client *client, 173 u8 reg) 174{ 175 return i2c_smbus_read_byte_data(client, reg); 176} 177 178static int 179bt819_init (struct i2c_client *client) 180{ 181 struct bt819 *decoder = i2c_get_clientdata(client); 182 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? 205 */ 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 */ 215 }; 216 217 struct timing *timing = &timing_data[decoder->norm]; 218 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); 237 238 /* init */ 239 return bt819_write_block(client, init, sizeof(init)); 240 241} 242 243/* ----------------------------------------------------------------------- */ 244 245static int 246bt819_command (struct i2c_client *client, 247 unsigned int cmd, 248 void *arg) 249{ 250 int temp; 251 252 struct bt819 *decoder = i2c_get_clientdata(client); 253 254 if (!decoder->initialized) { // First call to bt819_init could be 255 bt819_init(client); // without #FRST = 0 256 decoder->initialized = 1; 257 } 258 259 switch (cmd) { 260 261 case 0: 262 /* This is just for testing!!! */ 263 bt819_init(client); 264 break; 265 266 case DECODER_GET_CAPABILITIES: 267 { 268 struct video_decoder_capability *cap = arg; 269 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; 276 } 277 break; 278 279 case DECODER_GET_STATUS: 280 { 281 int *iarg = arg; 282 int status; 283 int res; 284 285 status = bt819_read(client, 0x00); 286 res = 0; 287 if ((status & 0x80)) { 288 res |= DECODER_STATUS_GOOD; 289 } 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; 303 } 304 break; 305 } 306 res |= DECODER_STATUS_COLOR; 307 *iarg = res; 308 309 dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client), 310 *iarg); 311 } 312 break; 313 314 case DECODER_SET_NORM: 315 { 316 int *iarg = arg; 317 struct timing *timing = NULL; 318 319 dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client), 320 *iarg); 321 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; 351 } 352 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); 365 } 366 367 decoder->norm = *iarg; 368 } 369 break; 370 371 case DECODER_SET_INPUT: 372 { 373 int *iarg = arg; 374 375 dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client), 376 *iarg); 377 378 if (*iarg < 0 || *iarg > 7) { 379 return -EINVAL; 380 } 381 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); 391 } 392 } 393 } 394 break; 395 396 case DECODER_SET_OUTPUT: 397 { 398 int *iarg = arg; 399 400 dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client), 401 *iarg); 402 403 /* not much choice of outputs */ 404 if (*iarg != 0) { 405 return -EINVAL; 406 } 407 } 408 break; 409 410 case DECODER_ENABLE_OUTPUT: 411 { 412 int *iarg = arg; 413 int enable = (*iarg != 0); 414 415 dprintk(1, KERN_INFO "%s: enable output %x\n", 416 I2C_NAME(client), *iarg); 417 418 if (decoder->enable != enable) { 419 decoder->enable = enable; 420 421 if (decoder->enable) { 422 bt819_setbit(client, 0x16, 7, 0); 423 } else { 424 bt819_setbit(client, 0x16, 7, 1); 425 } 426 } 427 } 428 break; 429 430 case DECODER_SET_PICTURE: 431 { 432 struct video_picture *pic = arg; 433 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); 439 440 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); 446 } 447 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)); 455 } 456 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)); 464 465 temp = (decoder->sat * 201) / 237; 466 bt819_write(client, 0x0e, (temp >> 7) & 0xff); 467 bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01); 468 } 469 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)); 475 } 476 } 477 break; 478 479 default: 480 return -EINVAL; 481 } 482 483 return 0; 484} 485 486/* ----------------------------------------------------------------------- */ 487 488/* 489 * Generic i2c probe 490 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' 491 */ 492static unsigned short normal_i2c[] = { 493 I2C_BT819 >> 1, 494 I2C_CLIENT_END, 495}; 496 497static unsigned short ignore = I2C_CLIENT_END; 498 499static struct i2c_client_address_data addr_data = { 500 .normal_i2c = normal_i2c, 501 .probe = &ignore, 502 .ignore = &ignore, 503}; 504 505static struct i2c_driver i2c_driver_bt819; 506 507static int 508bt819_detect_client (struct i2c_adapter *adapter, 509 int address, 510 int kind) 511{ 512 int i, id; 513 struct bt819 *decoder; 514 struct i2c_client *client; 515 516 dprintk(1, 517 KERN_INFO 518 "saa7111.c: detecting bt819 client on address 0x%x\n", 519 address << 1); 520 521 /* Check if the adapter supports the needed features */ 522 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 523 return 0; 524 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; 531 532 decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL); 533 if (decoder == NULL) { 534 kfree(client); 535 return -ENOMEM; 536 } 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); 546 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; 566 } 567 568 i = i2c_attach_client(client); 569 if (i) { 570 kfree(client); 571 kfree(decoder); 572 return i; 573 } 574 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); 585 } 586 587 return 0; 588} 589 590static int 591bt819_attach_adapter (struct i2c_adapter *adapter) 592{ 593 return i2c_probe(adapter, &addr_data, &bt819_detect_client); 594} 595 596static int 597bt819_detach_client (struct i2c_client *client) 598{ 599 struct bt819 *decoder = i2c_get_clientdata(client); 600 int err; 601 602 err = i2c_detach_client(client); 603 if (err) { 604 return err; 605 } 606 607 kfree(decoder); 608 kfree(client); 609 610 return 0; 611} 612 613/* ----------------------------------------------------------------------- */ 614 615static struct i2c_driver i2c_driver_bt819 = { 616 .driver = { 617 .name = "bt819", 618 }, 619 620 .id = I2C_DRIVERID_BT819, 621 622 .attach_adapter = bt819_attach_adapter, 623 .detach_client = bt819_detach_client, 624 .command = bt819_command, 625}; 626 627static int __init 628bt819_init_module (void) 629{ 630 return i2c_add_driver(&i2c_driver_bt819); 631} 632 633static void __exit 634bt819_exit (void) 635{ 636 i2c_del_driver(&i2c_driver_bt819); 637} 638 639module_init(bt819_init_module); 640module_exit(bt819_exit); 641