Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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