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