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 1220 lines 32 kB view raw
1/* 2 * saa7114 - Philips SAA7114H video decoder driver version 0.0.1 3 * 4 * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com> 5 * 6 * Based on saa7111 driver by Dave Perks 7 * 8 * Copyright (C) 1998 Dave Perks <dperks@ibm.net> 9 * 10 * Slight changes for video timing and attachment output by 11 * Wolfgang Scherr <scherr@net4you.net> 12 * 13 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net> 14 * - moved over to linux>=2.4.x i2c protocol (1/1/2003) 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 39#include <linux/slab.h> 40 41#include <linux/mm.h> 42#include <linux/pci.h> 43#include <linux/signal.h> 44#include <asm/io.h> 45#include <asm/pgtable.h> 46#include <asm/page.h> 47#include <linux/sched.h> 48#include <linux/types.h> 49 50#include <linux/videodev.h> 51#include <asm/uaccess.h> 52 53MODULE_DESCRIPTION("Philips SAA7114H video decoder driver"); 54MODULE_AUTHOR("Maxim Yevtyushkin"); 55MODULE_LICENSE("GPL"); 56 57#include <linux/i2c.h> 58 59#define I2C_NAME(x) (x)->name 60 61#include <linux/video_decoder.h> 62 63static int debug = 0; 64module_param(debug, int, 0); 65MODULE_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 75struct saa7114 { 76 unsigned char reg[0xf0 * 2]; 77 78 int norm; 79 int input; 80 int enable; 81 int bright; 82 int contrast; 83 int hue; 84 int sat; 85 int playback; 86}; 87 88#define I2C_SAA7114 0x42 89#define I2C_SAA7114A 0x40 90 91#define I2C_DELAY 10 92 93 94//#define SAA_7114_NTSC_HSYNC_START (-3) 95//#define SAA_7114_NTSC_HSYNC_STOP (-18) 96 97#define SAA_7114_NTSC_HSYNC_START (-17) 98#define SAA_7114_NTSC_HSYNC_STOP (-32) 99 100//#define SAA_7114_NTSC_HOFFSET (5) 101#define SAA_7114_NTSC_HOFFSET (6) 102#define SAA_7114_NTSC_VOFFSET (10) 103#define SAA_7114_NTSC_WIDTH (720) 104#define SAA_7114_NTSC_HEIGHT (250) 105 106#define SAA_7114_SECAM_HSYNC_START (-17) 107#define SAA_7114_SECAM_HSYNC_STOP (-32) 108 109#define SAA_7114_SECAM_HOFFSET (2) 110#define SAA_7114_SECAM_VOFFSET (10) 111#define SAA_7114_SECAM_WIDTH (720) 112#define SAA_7114_SECAM_HEIGHT (300) 113 114#define SAA_7114_PAL_HSYNC_START (-17) 115#define SAA_7114_PAL_HSYNC_STOP (-32) 116 117#define SAA_7114_PAL_HOFFSET (2) 118#define SAA_7114_PAL_VOFFSET (10) 119#define SAA_7114_PAL_WIDTH (720) 120#define SAA_7114_PAL_HEIGHT (300) 121 122 123 124#define SAA_7114_VERTICAL_CHROMA_OFFSET 0 //0x50504040 125#define SAA_7114_VERTICAL_LUMA_OFFSET 0 126 127#define REG_ADDR(x) (((x) << 1) + 1) 128#define LOBYTE(x) ((unsigned char)((x) & 0xff)) 129#define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff)) 130#define LOWORD(x) ((unsigned short int)((x) & 0xffff)) 131#define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff)) 132 133 134/* ----------------------------------------------------------------------- */ 135 136static inline int 137saa7114_write (struct i2c_client *client, 138 u8 reg, 139 u8 value) 140{ 141 return i2c_smbus_write_byte_data(client, reg, value); 142} 143 144static int 145saa7114_write_block (struct i2c_client *client, 146 const u8 *data, 147 unsigned int len) 148{ 149 int ret = -1; 150 u8 reg; 151 152 /* the saa7114 has an autoincrement function, use it if 153 * the adapter understands raw I2C */ 154 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 155 /* do raw I2C, not smbus compatible */ 156 u8 block_data[32]; 157 int block_len; 158 159 while (len >= 2) { 160 block_len = 0; 161 block_data[block_len++] = reg = data[0]; 162 do { 163 block_data[block_len++] = data[1]; 164 reg++; 165 len -= 2; 166 data += 2; 167 } while (len >= 2 && data[0] == reg && 168 block_len < 32); 169 if ((ret = i2c_master_send(client, block_data, 170 block_len)) < 0) 171 break; 172 } 173 } else { 174 /* do some slow I2C emulation kind of thing */ 175 while (len >= 2) { 176 reg = *data++; 177 if ((ret = saa7114_write(client, reg, 178 *data++)) < 0) 179 break; 180 len -= 2; 181 } 182 } 183 184 return ret; 185} 186 187static inline int 188saa7114_read (struct i2c_client *client, 189 u8 reg) 190{ 191 return i2c_smbus_read_byte_data(client, reg); 192} 193 194/* ----------------------------------------------------------------------- */ 195 196// initially set NTSC, composite 197 198 199static const unsigned char init[] = { 200 0x00, 0x00, /* 00 - ID byte , chip version, 201 * read only */ 202 0x01, 0x08, /* 01 - X,X,X,X, IDEL3 to IDEL0 - 203 * horizontal increment delay, 204 * recommended position */ 205 0x02, 0x00, /* 02 - FUSE=3, GUDL=2, MODE=0 ; 206 * input control */ 207 0x03, 0x10, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, 208 * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */ 209 0x04, 0x90, /* 04 - GAI1=256 */ 210 0x05, 0x90, /* 05 - GAI2=256 */ 211 0x06, SAA_7114_NTSC_HSYNC_START, /* 06 - HSB: hsync start, 212 * depends on the video standard */ 213 0x07, SAA_7114_NTSC_HSYNC_STOP, /* 07 - HSS: hsync stop, depends 214 *on the video standard */ 215 0x08, 0xb8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1, 216 * HPLL: free running in playback, locked 217 * in capture, VNOI=0 */ 218 0x09, 0x80, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0, 219 * UPTCV=0, APER=1; depends from input */ 220 0x0a, 0x80, /* 0a - BRIG=128 */ 221 0x0b, 0x44, /* 0b - CONT=1.109 */ 222 0x0c, 0x40, /* 0c - SATN=1.0 */ 223 0x0d, 0x00, /* 0d - HUE=0 */ 224 0x0e, 0x84, /* 0e - CDTO, CSTD2 to 0, DCVF, FCTC, 225 * CCOMB; depends from video standard */ 226 0x0f, 0x24, /* 0f - ACGC,CGAIN6 to CGAIN0; depends 227 * from video standard */ 228 0x10, 0x03, /* 10 - OFFU1 to 0, OFFV1 to 0, CHBW, 229 * LCBW2 to 0 */ 230 0x11, 0x59, /* 11 - COLO, RTP1, HEDL1 to 0, RTP0, 231 * YDEL2 to 0 */ 232 0x12, 0xc9, /* 12 - RT signal control RTSE13 to 10 233 * and 03 to 00 */ 234 0x13, 0x80, /* 13 - RT/X port output control */ 235 0x14, 0x00, /* 14 - analog, ADC, compatibility control */ 236 0x15, 0x00, /* 15 - VGATE start FID change */ 237 0x16, 0xfe, /* 16 - VGATE stop */ 238 0x17, 0x00, /* 17 - Misc., VGATE MSBs */ 239 0x18, 0x40, /* RAWG */ 240 0x19, 0x80, /* RAWO */ 241 0x1a, 0x00, 242 0x1b, 0x00, 243 0x1c, 0x00, 244 0x1d, 0x00, 245 0x1e, 0x00, 246 0x1f, 0x00, /* status byte, read only */ 247 0x20, 0x00, /* video decoder reserved part */ 248 0x21, 0x00, 249 0x22, 0x00, 250 0x23, 0x00, 251 0x24, 0x00, 252 0x25, 0x00, 253 0x26, 0x00, 254 0x27, 0x00, 255 0x28, 0x00, 256 0x29, 0x00, 257 0x2a, 0x00, 258 0x2b, 0x00, 259 0x2c, 0x00, 260 0x2d, 0x00, 261 0x2e, 0x00, 262 0x2f, 0x00, 263 0x30, 0xbc, /* audio clock generator */ 264 0x31, 0xdf, 265 0x32, 0x02, 266 0x33, 0x00, 267 0x34, 0xcd, 268 0x35, 0xcc, 269 0x36, 0x3a, 270 0x37, 0x00, 271 0x38, 0x03, 272 0x39, 0x10, 273 0x3a, 0x00, 274 0x3b, 0x00, 275 0x3c, 0x00, 276 0x3d, 0x00, 277 0x3e, 0x00, 278 0x3f, 0x00, 279 0x40, 0x00, /* VBI data slicer */ 280 0x41, 0xff, 281 0x42, 0xff, 282 0x43, 0xff, 283 0x44, 0xff, 284 0x45, 0xff, 285 0x46, 0xff, 286 0x47, 0xff, 287 0x48, 0xff, 288 0x49, 0xff, 289 0x4a, 0xff, 290 0x4b, 0xff, 291 0x4c, 0xff, 292 0x4d, 0xff, 293 0x4e, 0xff, 294 0x4f, 0xff, 295 0x50, 0xff, 296 0x51, 0xff, 297 0x52, 0xff, 298 0x53, 0xff, 299 0x54, 0xff, 300 0x55, 0xff, 301 0x56, 0xff, 302 0x57, 0xff, 303 0x58, 0x40, // framing code 304 0x59, 0x47, // horizontal offset 305 0x5a, 0x06, // vertical offset 306 0x5b, 0x83, // field offset 307 0x5c, 0x00, // reserved 308 0x5d, 0x3e, // header and data 309 0x5e, 0x00, // sliced data 310 0x5f, 0x00, // reserved 311 0x60, 0x00, /* video decoder reserved part */ 312 0x61, 0x00, 313 0x62, 0x00, 314 0x63, 0x00, 315 0x64, 0x00, 316 0x65, 0x00, 317 0x66, 0x00, 318 0x67, 0x00, 319 0x68, 0x00, 320 0x69, 0x00, 321 0x6a, 0x00, 322 0x6b, 0x00, 323 0x6c, 0x00, 324 0x6d, 0x00, 325 0x6e, 0x00, 326 0x6f, 0x00, 327 0x70, 0x00, /* video decoder reserved part */ 328 0x71, 0x00, 329 0x72, 0x00, 330 0x73, 0x00, 331 0x74, 0x00, 332 0x75, 0x00, 333 0x76, 0x00, 334 0x77, 0x00, 335 0x78, 0x00, 336 0x79, 0x00, 337 0x7a, 0x00, 338 0x7b, 0x00, 339 0x7c, 0x00, 340 0x7d, 0x00, 341 0x7e, 0x00, 342 0x7f, 0x00, 343 0x80, 0x00, /* X-port, I-port and scaler */ 344 0x81, 0x00, 345 0x82, 0x00, 346 0x83, 0x00, 347 0x84, 0xc5, 348 0x85, 0x0d, // hsync and vsync ? 349 0x86, 0x40, 350 0x87, 0x01, 351 0x88, 0x00, 352 0x89, 0x00, 353 0x8a, 0x00, 354 0x8b, 0x00, 355 0x8c, 0x00, 356 0x8d, 0x00, 357 0x8e, 0x00, 358 0x8f, 0x00, 359 0x90, 0x03, /* Task A definition */ 360 0x91, 0x08, 361 0x92, 0x00, 362 0x93, 0x40, 363 0x94, 0x00, // window settings 364 0x95, 0x00, 365 0x96, 0x00, 366 0x97, 0x00, 367 0x98, 0x00, 368 0x99, 0x00, 369 0x9a, 0x00, 370 0x9b, 0x00, 371 0x9c, 0x00, 372 0x9d, 0x00, 373 0x9e, 0x00, 374 0x9f, 0x00, 375 0xa0, 0x01, /* horizontal integer prescaling ratio */ 376 0xa1, 0x00, /* horizontal prescaler accumulation 377 * sequence length */ 378 0xa2, 0x00, /* UV FIR filter, Y FIR filter, prescaler 379 * DC gain */ 380 0xa3, 0x00, 381 0xa4, 0x80, // luminance brightness 382 0xa5, 0x40, // luminance gain 383 0xa6, 0x40, // chrominance saturation 384 0xa7, 0x00, 385 0xa8, 0x00, // horizontal luminance scaling increment 386 0xa9, 0x04, 387 0xaa, 0x00, // horizontal luminance phase offset 388 0xab, 0x00, 389 0xac, 0x00, // horizontal chrominance scaling increment 390 0xad, 0x02, 391 0xae, 0x00, // horizontal chrominance phase offset 392 0xaf, 0x00, 393 0xb0, 0x00, // vertical luminance scaling increment 394 0xb1, 0x04, 395 0xb2, 0x00, // vertical chrominance scaling increment 396 0xb3, 0x04, 397 0xb4, 0x00, 398 0xb5, 0x00, 399 0xb6, 0x00, 400 0xb7, 0x00, 401 0xb8, 0x00, 402 0xb9, 0x00, 403 0xba, 0x00, 404 0xbb, 0x00, 405 0xbc, 0x00, 406 0xbd, 0x00, 407 0xbe, 0x00, 408 0xbf, 0x00, 409 0xc0, 0x02, // Task B definition 410 0xc1, 0x08, 411 0xc2, 0x00, 412 0xc3, 0x40, 413 0xc4, 0x00, // window settings 414 0xc5, 0x00, 415 0xc6, 0x00, 416 0xc7, 0x00, 417 0xc8, 0x00, 418 0xc9, 0x00, 419 0xca, 0x00, 420 0xcb, 0x00, 421 0xcc, 0x00, 422 0xcd, 0x00, 423 0xce, 0x00, 424 0xcf, 0x00, 425 0xd0, 0x01, // horizontal integer prescaling ratio 426 0xd1, 0x00, // horizontal prescaler accumulation sequence length 427 0xd2, 0x00, // UV FIR filter, Y FIR filter, prescaler DC gain 428 0xd3, 0x00, 429 0xd4, 0x80, // luminance brightness 430 0xd5, 0x40, // luminance gain 431 0xd6, 0x40, // chrominance saturation 432 0xd7, 0x00, 433 0xd8, 0x00, // horizontal luminance scaling increment 434 0xd9, 0x04, 435 0xda, 0x00, // horizontal luminance phase offset 436 0xdb, 0x00, 437 0xdc, 0x00, // horizontal chrominance scaling increment 438 0xdd, 0x02, 439 0xde, 0x00, // horizontal chrominance phase offset 440 0xdf, 0x00, 441 0xe0, 0x00, // vertical luminance scaling increment 442 0xe1, 0x04, 443 0xe2, 0x00, // vertical chrominance scaling increment 444 0xe3, 0x04, 445 0xe4, 0x00, 446 0xe5, 0x00, 447 0xe6, 0x00, 448 0xe7, 0x00, 449 0xe8, 0x00, 450 0xe9, 0x00, 451 0xea, 0x00, 452 0xeb, 0x00, 453 0xec, 0x00, 454 0xed, 0x00, 455 0xee, 0x00, 456 0xef, 0x00 457}; 458 459static int 460saa7114_command (struct i2c_client *client, 461 unsigned int cmd, 462 void *arg) 463{ 464 struct saa7114 *decoder = i2c_get_clientdata(client); 465 466 switch (cmd) { 467 468 case 0: 469 //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client)); 470 //saa7114_write_block(client, init, sizeof(init)); 471 break; 472 473 case DECODER_DUMP: 474 { 475 int i; 476 477 dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client)); 478 479 for (i = 0; i < 32; i += 16) { 480 int j; 481 482 printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i); 483 for (j = 0; j < 16; ++j) { 484 printk(" %02x", 485 saa7114_read(client, i + j)); 486 } 487 printk("\n"); 488 } 489 } 490 break; 491 492 case DECODER_GET_CAPABILITIES: 493 { 494 struct video_decoder_capability *cap = arg; 495 496 dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n", 497 I2C_NAME(client)); 498 499 cap->flags = VIDEO_DECODER_PAL | 500 VIDEO_DECODER_NTSC | 501 VIDEO_DECODER_AUTO | 502 VIDEO_DECODER_CCIR; 503 cap->inputs = 8; 504 cap->outputs = 1; 505 } 506 break; 507 508 case DECODER_GET_STATUS: 509 { 510 int *iarg = arg; 511 int status; 512 int res; 513 514 status = saa7114_read(client, 0x1f); 515 516 dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client), 517 status); 518 res = 0; 519 if ((status & (1 << 6)) == 0) { 520 res |= DECODER_STATUS_GOOD; 521 } 522 switch (decoder->norm) { 523 case VIDEO_MODE_NTSC: 524 res |= DECODER_STATUS_NTSC; 525 break; 526 case VIDEO_MODE_PAL: 527 res |= DECODER_STATUS_PAL; 528 break; 529 case VIDEO_MODE_SECAM: 530 res |= DECODER_STATUS_SECAM; 531 break; 532 default: 533 case VIDEO_MODE_AUTO: 534 if ((status & (1 << 5)) != 0) { 535 res |= DECODER_STATUS_NTSC; 536 } else { 537 res |= DECODER_STATUS_PAL; 538 } 539 break; 540 } 541 if ((status & (1 << 0)) != 0) { 542 res |= DECODER_STATUS_COLOR; 543 } 544 *iarg = res; 545 } 546 break; 547 548 case DECODER_SET_NORM: 549 { 550 int *iarg = arg; 551 552 short int hoff = 0, voff = 0, w = 0, h = 0; 553 554 dprintk(1, KERN_DEBUG "%s: decoder set norm ", 555 I2C_NAME(client)); 556 switch (*iarg) { 557 558 case VIDEO_MODE_NTSC: 559 dprintk(1, "NTSC\n"); 560 decoder->reg[REG_ADDR(0x06)] = 561 SAA_7114_NTSC_HSYNC_START; 562 decoder->reg[REG_ADDR(0x07)] = 563 SAA_7114_NTSC_HSYNC_STOP; 564 565 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture 566 567 decoder->reg[REG_ADDR(0x0e)] = 0x85; 568 decoder->reg[REG_ADDR(0x0f)] = 0x24; 569 570 hoff = SAA_7114_NTSC_HOFFSET; 571 voff = SAA_7114_NTSC_VOFFSET; 572 w = SAA_7114_NTSC_WIDTH; 573 h = SAA_7114_NTSC_HEIGHT; 574 575 break; 576 577 case VIDEO_MODE_PAL: 578 dprintk(1, "PAL\n"); 579 decoder->reg[REG_ADDR(0x06)] = 580 SAA_7114_PAL_HSYNC_START; 581 decoder->reg[REG_ADDR(0x07)] = 582 SAA_7114_PAL_HSYNC_STOP; 583 584 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture 585 586 decoder->reg[REG_ADDR(0x0e)] = 0x81; 587 decoder->reg[REG_ADDR(0x0f)] = 0x24; 588 589 hoff = SAA_7114_PAL_HOFFSET; 590 voff = SAA_7114_PAL_VOFFSET; 591 w = SAA_7114_PAL_WIDTH; 592 h = SAA_7114_PAL_HEIGHT; 593 594 break; 595 596 default: 597 dprintk(1, " Unknown video mode!!!\n"); 598 return -EINVAL; 599 600 } 601 602 603 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low 604 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high 605 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low 606 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high 607 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low 608 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high 609 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low 610 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high 611 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low 612 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high 613 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low 614 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high 615 616 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low 617 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high 618 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low 619 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high 620 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low 621 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high 622 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low 623 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high 624 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low 625 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high 626 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low 627 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high 628 629 630 saa7114_write(client, 0x80, 0x06); // i-port and scaler back end clock selection, task A&B off 631 saa7114_write(client, 0x88, 0xd8); // sw reset scaler 632 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release 633 634 saa7114_write_block(client, decoder->reg + (0x06 << 1), 635 3 << 1); 636 saa7114_write_block(client, decoder->reg + (0x0e << 1), 637 2 << 1); 638 saa7114_write_block(client, decoder->reg + (0x5a << 1), 639 2 << 1); 640 641 saa7114_write_block(client, decoder->reg + (0x94 << 1), 642 (0x9f + 1 - 0x94) << 1); 643 saa7114_write_block(client, decoder->reg + (0xc4 << 1), 644 (0xcf + 1 - 0xc4) << 1); 645 646 saa7114_write(client, 0x88, 0xd8); // sw reset scaler 647 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release 648 saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection 649 650 decoder->norm = *iarg; 651 } 652 break; 653 654 case DECODER_SET_INPUT: 655 { 656 int *iarg = arg; 657 658 dprintk(1, KERN_DEBUG "%s: decoder set input (%d)\n", 659 I2C_NAME(client), *iarg); 660 if (*iarg < 0 || *iarg > 7) { 661 return -EINVAL; 662 } 663 664 if (decoder->input != *iarg) { 665 dprintk(1, KERN_DEBUG "%s: now setting %s input\n", 666 I2C_NAME(client), 667 *iarg >= 6 ? "S-Video" : "Composite"); 668 decoder->input = *iarg; 669 670 /* select mode */ 671 decoder->reg[REG_ADDR(0x02)] = 672 (decoder-> 673 reg[REG_ADDR(0x02)] & 0xf0) | (decoder-> 674 input < 675 6 ? 0x0 : 0x9); 676 saa7114_write(client, 0x02, 677 decoder->reg[REG_ADDR(0x02)]); 678 679 /* bypass chrominance trap for modes 6..9 */ 680 decoder->reg[REG_ADDR(0x09)] = 681 (decoder-> 682 reg[REG_ADDR(0x09)] & 0x7f) | (decoder-> 683 input < 684 6 ? 0x0 : 685 0x80); 686 saa7114_write(client, 0x09, 687 decoder->reg[REG_ADDR(0x09)]); 688 689 decoder->reg[REG_ADDR(0x0e)] = 690 decoder->input < 691 6 ? decoder-> 692 reg[REG_ADDR(0x0e)] | 1 : decoder-> 693 reg[REG_ADDR(0x0e)] & ~1; 694 saa7114_write(client, 0x0e, 695 decoder->reg[REG_ADDR(0x0e)]); 696 } 697 } 698 break; 699 700 case DECODER_SET_OUTPUT: 701 { 702 int *iarg = arg; 703 704 dprintk(1, KERN_DEBUG "%s: decoder set output\n", 705 I2C_NAME(client)); 706 707 /* not much choice of outputs */ 708 if (*iarg != 0) { 709 return -EINVAL; 710 } 711 } 712 break; 713 714 case DECODER_ENABLE_OUTPUT: 715 { 716 int *iarg = arg; 717 int enable = (*iarg != 0); 718 719 dprintk(1, KERN_DEBUG "%s: decoder %s output\n", 720 I2C_NAME(client), enable ? "enable" : "disable"); 721 722 decoder->playback = !enable; 723 724 if (decoder->enable != enable) { 725 decoder->enable = enable; 726 727 /* RJ: If output should be disabled (for 728 * playing videos), we also need a open PLL. 729 * The input is set to 0 (where no input 730 * source is connected), although this 731 * is not necessary. 732 * 733 * If output should be enabled, we have to 734 * reverse the above. 735 */ 736 737 if (decoder->enable) { 738 decoder->reg[REG_ADDR(0x08)] = 0xb8; 739 decoder->reg[REG_ADDR(0x12)] = 0xc9; 740 decoder->reg[REG_ADDR(0x13)] = 0x80; 741 decoder->reg[REG_ADDR(0x87)] = 0x01; 742 } else { 743 decoder->reg[REG_ADDR(0x08)] = 0x7c; 744 decoder->reg[REG_ADDR(0x12)] = 0x00; 745 decoder->reg[REG_ADDR(0x13)] = 0x00; 746 decoder->reg[REG_ADDR(0x87)] = 0x00; 747 } 748 749 saa7114_write_block(client, 750 decoder->reg + (0x12 << 1), 751 2 << 1); 752 saa7114_write(client, 0x08, 753 decoder->reg[REG_ADDR(0x08)]); 754 saa7114_write(client, 0x87, 755 decoder->reg[REG_ADDR(0x87)]); 756 saa7114_write(client, 0x88, 0xd8); // sw reset scaler 757 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release 758 saa7114_write(client, 0x80, 0x36); 759 760 } 761 } 762 break; 763 764 case DECODER_SET_PICTURE: 765 { 766 struct video_picture *pic = arg; 767 768 dprintk(1, 769 KERN_DEBUG 770 "%s: decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n", 771 I2C_NAME(client), pic->brightness, pic->contrast, 772 pic->colour, pic->hue); 773 774 if (decoder->bright != pic->brightness) { 775 /* We want 0 to 255 we get 0-65535 */ 776 decoder->bright = pic->brightness; 777 saa7114_write(client, 0x0a, decoder->bright >> 8); 778 } 779 if (decoder->contrast != pic->contrast) { 780 /* We want 0 to 127 we get 0-65535 */ 781 decoder->contrast = pic->contrast; 782 saa7114_write(client, 0x0b, 783 decoder->contrast >> 9); 784 } 785 if (decoder->sat != pic->colour) { 786 /* We want 0 to 127 we get 0-65535 */ 787 decoder->sat = pic->colour; 788 saa7114_write(client, 0x0c, decoder->sat >> 9); 789 } 790 if (decoder->hue != pic->hue) { 791 /* We want -128 to 127 we get 0-65535 */ 792 decoder->hue = pic->hue; 793 saa7114_write(client, 0x0d, 794 (decoder->hue - 32768) >> 8); 795 } 796 } 797 break; 798 799 default: 800 return -EINVAL; 801 } 802 803 return 0; 804} 805 806/* ----------------------------------------------------------------------- */ 807 808/* 809 * Generic i2c probe 810 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' 811 */ 812static unsigned short normal_i2c[] = 813 { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END }; 814 815static unsigned short ignore = I2C_CLIENT_END; 816 817static struct i2c_client_address_data addr_data = { 818 .normal_i2c = normal_i2c, 819 .probe = &ignore, 820 .ignore = &ignore, 821}; 822 823static struct i2c_driver i2c_driver_saa7114; 824 825static int 826saa7114_detect_client (struct i2c_adapter *adapter, 827 int address, 828 int kind) 829{ 830 int i, err[30]; 831 short int hoff = SAA_7114_NTSC_HOFFSET; 832 short int voff = SAA_7114_NTSC_VOFFSET; 833 short int w = SAA_7114_NTSC_WIDTH; 834 short int h = SAA_7114_NTSC_HEIGHT; 835 struct i2c_client *client; 836 struct saa7114 *decoder; 837 838 dprintk(1, 839 KERN_INFO 840 "saa7114.c: detecting saa7114 client on address 0x%x\n", 841 address << 1); 842 843 /* Check if the adapter supports the needed features */ 844 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 845 return 0; 846 847 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); 848 if (client == 0) 849 return -ENOMEM; 850 client->addr = address; 851 client->adapter = adapter; 852 client->driver = &i2c_driver_saa7114; 853 strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client))); 854 855 decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL); 856 if (decoder == NULL) { 857 kfree(client); 858 return -ENOMEM; 859 } 860 decoder->norm = VIDEO_MODE_NTSC; 861 decoder->input = -1; 862 decoder->enable = 1; 863 decoder->bright = 32768; 864 decoder->contrast = 32768; 865 decoder->hue = 32768; 866 decoder->sat = 32768; 867 decoder->playback = 0; // initially capture mode useda 868 i2c_set_clientdata(client, decoder); 869 870 memcpy(decoder->reg, init, sizeof(init)); 871 872 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low 873 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high 874 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low 875 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high 876 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low 877 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high 878 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low 879 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high 880 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low 881 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high 882 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low 883 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high 884 885 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low 886 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high 887 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low 888 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high 889 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low 890 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high 891 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low 892 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high 893 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low 894 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high 895 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low 896 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high 897 898 decoder->reg[REG_ADDR(0xb8)] = 899 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); 900 decoder->reg[REG_ADDR(0xb9)] = 901 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); 902 decoder->reg[REG_ADDR(0xba)] = 903 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); 904 decoder->reg[REG_ADDR(0xbb)] = 905 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); 906 907 decoder->reg[REG_ADDR(0xbc)] = 908 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); 909 decoder->reg[REG_ADDR(0xbd)] = 910 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); 911 decoder->reg[REG_ADDR(0xbe)] = 912 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); 913 decoder->reg[REG_ADDR(0xbf)] = 914 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); 915 916 decoder->reg[REG_ADDR(0xe8)] = 917 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); 918 decoder->reg[REG_ADDR(0xe9)] = 919 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); 920 decoder->reg[REG_ADDR(0xea)] = 921 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); 922 decoder->reg[REG_ADDR(0xeb)] = 923 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); 924 925 decoder->reg[REG_ADDR(0xec)] = 926 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); 927 decoder->reg[REG_ADDR(0xed)] = 928 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); 929 decoder->reg[REG_ADDR(0xee)] = 930 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); 931 decoder->reg[REG_ADDR(0xef)] = 932 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); 933 934 935 decoder->reg[REG_ADDR(0x13)] = 0x80; // RTC0 on 936 decoder->reg[REG_ADDR(0x87)] = 0x01; // I-Port 937 decoder->reg[REG_ADDR(0x12)] = 0xc9; // RTS0 938 939 decoder->reg[REG_ADDR(0x02)] = 0xc0; // set composite1 input, aveasy 940 decoder->reg[REG_ADDR(0x09)] = 0x00; // chrominance trap 941 decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on 942 943 944 dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n", 945 I2C_NAME(client)); 946 947 err[0] = 948 saa7114_write_block(client, decoder->reg + (0x20 << 1), 949 0x10 << 1); 950 err[1] = 951 saa7114_write_block(client, decoder->reg + (0x30 << 1), 952 0x10 << 1); 953 err[2] = 954 saa7114_write_block(client, decoder->reg + (0x63 << 1), 955 (0x7f + 1 - 0x63) << 1); 956 err[3] = 957 saa7114_write_block(client, decoder->reg + (0x89 << 1), 958 6 << 1); 959 err[4] = 960 saa7114_write_block(client, decoder->reg + (0xb8 << 1), 961 8 << 1); 962 err[5] = 963 saa7114_write_block(client, decoder->reg + (0xe8 << 1), 964 8 << 1); 965 966 967 for (i = 0; i <= 5; i++) { 968 if (err[i] < 0) { 969 dprintk(1, 970 KERN_ERR 971 "%s_attach: init error %d at stage %d, leaving attach.\n", 972 I2C_NAME(client), i, err[i]); 973 kfree(decoder); 974 kfree(client); 975 return 0; 976 } 977 } 978 979 for (i = 6; i < 8; i++) { 980 dprintk(1, 981 KERN_DEBUG 982 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n", 983 I2C_NAME(client), i, saa7114_read(client, i), 984 decoder->reg[REG_ADDR(i)]); 985 } 986 987 dprintk(1, 988 KERN_DEBUG 989 "%s_attach: performing decoder reset sequence\n", 990 I2C_NAME(client)); 991 992 err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off 993 err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler 994 err[8] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release 995 996 for (i = 6; i <= 8; i++) { 997 if (err[i] < 0) { 998 dprintk(1, 999 KERN_ERR 1000 "%s_attach: init error %d at stage %d, leaving attach.\n", 1001 I2C_NAME(client), i, err[i]); 1002 kfree(decoder); 1003 kfree(client); 1004 return 0; 1005 } 1006 } 1007 1008 dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n", 1009 I2C_NAME(client)); 1010 1011 1012 err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]); 1013 err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq 1014 err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1); // slicer 1015 err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1); // ? 1016 err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1); // ? 1017 err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1); // Task A 1018 err[15] = 1019 saa7114_write_block(client, decoder->reg + (0x94 << 1), 1020 12 << 1); 1021 err[16] = 1022 saa7114_write_block(client, decoder->reg + (0xa0 << 1), 1023 8 << 1); 1024 err[17] = 1025 saa7114_write_block(client, decoder->reg + (0xa8 << 1), 1026 8 << 1); 1027 err[18] = 1028 saa7114_write_block(client, decoder->reg + (0xb0 << 1), 1029 8 << 1); 1030 err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1); // Task B 1031 err[15] = 1032 saa7114_write_block(client, decoder->reg + (0xc4 << 1), 1033 12 << 1); 1034 err[16] = 1035 saa7114_write_block(client, decoder->reg + (0xd0 << 1), 1036 8 << 1); 1037 err[17] = 1038 saa7114_write_block(client, decoder->reg + (0xd8 << 1), 1039 8 << 1); 1040 err[18] = 1041 saa7114_write_block(client, decoder->reg + (0xe0 << 1), 1042 8 << 1); 1043 1044 for (i = 9; i <= 18; i++) { 1045 if (err[i] < 0) { 1046 dprintk(1, 1047 KERN_ERR 1048 "%s_attach: init error %d at stage %d, leaving attach.\n", 1049 I2C_NAME(client), i, err[i]); 1050 kfree(decoder); 1051 kfree(client); 1052 return 0; 1053 } 1054 } 1055 1056 1057 for (i = 6; i < 8; i++) { 1058 dprintk(1, 1059 KERN_DEBUG 1060 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n", 1061 I2C_NAME(client), i, saa7114_read(client, i), 1062 decoder->reg[REG_ADDR(i)]); 1063 } 1064 1065 1066 for (i = 0x11; i <= 0x13; i++) { 1067 dprintk(1, 1068 KERN_DEBUG 1069 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n", 1070 I2C_NAME(client), i, saa7114_read(client, i), 1071 decoder->reg[REG_ADDR(i)]); 1072 } 1073 1074 1075 dprintk(1, KERN_DEBUG "%s_attach: setting video input\n", 1076 I2C_NAME(client)); 1077 1078 err[19] = 1079 saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]); 1080 err[20] = 1081 saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]); 1082 err[21] = 1083 saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]); 1084 1085 for (i = 19; i <= 21; i++) { 1086 if (err[i] < 0) { 1087 dprintk(1, 1088 KERN_ERR 1089 "%s_attach: init error %d at stage %d, leaving attach.\n", 1090 I2C_NAME(client), i, err[i]); 1091 kfree(decoder); 1092 kfree(client); 1093 return 0; 1094 } 1095 } 1096 1097 dprintk(1, 1098 KERN_DEBUG 1099 "%s_attach: performing decoder reset sequence\n", 1100 I2C_NAME(client)); 1101 1102 err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler 1103 err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release 1104 err[24] = saa7114_write(client, 0x80, 0x36); // i-port and scaler backend clock selection, task A&B off 1105 1106 1107 for (i = 22; i <= 24; i++) { 1108 if (err[i] < 0) { 1109 dprintk(1, 1110 KERN_ERR 1111 "%s_attach: init error %d at stage %d, leaving attach.\n", 1112 I2C_NAME(client), i, err[i]); 1113 kfree(decoder); 1114 kfree(client); 1115 return 0; 1116 } 1117 } 1118 1119 err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]); 1120 err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]); 1121 err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]); 1122 1123 dprintk(1, 1124 KERN_INFO 1125 "%s_attach: chip version %x, decoder status 0x%02x\n", 1126 I2C_NAME(client), saa7114_read(client, 0x00) >> 4, 1127 saa7114_read(client, 0x1f)); 1128 dprintk(1, 1129 KERN_DEBUG 1130 "%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n", 1131 I2C_NAME(client), saa7114_read(client, 0x88), 1132 saa7114_read(client, 0x8f)); 1133 1134 1135 for (i = 0x94; i < 0x96; i++) { 1136 dprintk(1, 1137 KERN_DEBUG 1138 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n", 1139 I2C_NAME(client), i, saa7114_read(client, i), 1140 decoder->reg[REG_ADDR(i)]); 1141 } 1142 1143 i = i2c_attach_client(client); 1144 if (i) { 1145 kfree(client); 1146 kfree(decoder); 1147 return i; 1148 } 1149 1150 //i = saa7114_write_block(client, init, sizeof(init)); 1151 i = 0; 1152 if (i < 0) { 1153 dprintk(1, KERN_ERR "%s_attach error: init status %d\n", 1154 I2C_NAME(client), i); 1155 } else { 1156 dprintk(1, 1157 KERN_INFO 1158 "%s_attach: chip version %x at address 0x%x\n", 1159 I2C_NAME(client), saa7114_read(client, 0x00) >> 4, 1160 client->addr << 1); 1161 } 1162 1163 return 0; 1164} 1165 1166static int 1167saa7114_attach_adapter (struct i2c_adapter *adapter) 1168{ 1169 dprintk(1, 1170 KERN_INFO 1171 "saa7114.c: starting probe for adapter %s (0x%x)\n", 1172 I2C_NAME(adapter), adapter->id); 1173 return i2c_probe(adapter, &addr_data, &saa7114_detect_client); 1174} 1175 1176static int 1177saa7114_detach_client (struct i2c_client *client) 1178{ 1179 struct saa7114 *decoder = i2c_get_clientdata(client); 1180 int err; 1181 1182 err = i2c_detach_client(client); 1183 if (err) { 1184 return err; 1185 } 1186 1187 kfree(decoder); 1188 kfree(client); 1189 1190 return 0; 1191} 1192 1193/* ----------------------------------------------------------------------- */ 1194 1195static struct i2c_driver i2c_driver_saa7114 = { 1196 .driver = { 1197 .name = "saa7114", 1198 }, 1199 1200 .id = I2C_DRIVERID_SAA7114, 1201 1202 .attach_adapter = saa7114_attach_adapter, 1203 .detach_client = saa7114_detach_client, 1204 .command = saa7114_command, 1205}; 1206 1207static int __init 1208saa7114_init (void) 1209{ 1210 return i2c_add_driver(&i2c_driver_saa7114); 1211} 1212 1213static void __exit 1214saa7114_exit (void) 1215{ 1216 i2c_del_driver(&i2c_driver_saa7114); 1217} 1218 1219module_init(saa7114_init); 1220module_exit(saa7114_exit);