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 919 lines 23 kB view raw
1#include <linux/module.h> 2#include <linux/moduleparam.h> 3#include <linux/kernel.h> 4#include <linux/i2c.h> 5#include <linux/types.h> 6#include <linux/videodev.h> 7#include <linux/init.h> 8#include <linux/errno.h> 9#include <linux/slab.h> 10#include <linux/delay.h> 11 12#include <media/v4l2-common.h> 13#include <media/tuner.h> 14 15 16/* Chips: 17 TDA9885 (PAL, NTSC) 18 TDA9886 (PAL, SECAM, NTSC) 19 TDA9887 (PAL, SECAM, NTSC, FM Radio) 20 21 found on: 22 - Pinnacle PCTV (Jul.2002 Version with MT2032, bttv) 23 TDA9887 (world), TDA9885 (USA) 24 Note: OP2 of tda988x must be set to 1, else MT2032 is disabled! 25 - KNC One TV-Station RDS (saa7134) 26 - Hauppauge PVR-150/500 (possibly more) 27*/ 28 29 30/* Addresses to scan */ 31static unsigned short normal_i2c[] = { 32 0x84 >>1, 33 0x86 >>1, 34 0x96 >>1, 35 I2C_CLIENT_END, 36}; 37I2C_CLIENT_INSMOD; 38 39/* insmod options */ 40static unsigned int debug = 0; 41module_param(debug, int, 0644); 42MODULE_LICENSE("GPL"); 43 44/* ---------------------------------------------------------------------- */ 45 46#define UNSET (-1U) 47#define tda9887_info(fmt, arg...) do {\ 48 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \ 49 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0) 50#define tda9887_dbg(fmt, arg...) do {\ 51 if (debug) \ 52 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \ 53 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0) 54 55struct tda9887 { 56 struct i2c_client client; 57 v4l2_std_id std; 58 enum tuner_mode mode; 59 unsigned int config; 60 unsigned int using_v4l2; 61 unsigned int radio_mode; 62 unsigned char data[4]; 63}; 64 65struct tvnorm { 66 v4l2_std_id std; 67 char *name; 68 unsigned char b; 69 unsigned char c; 70 unsigned char e; 71}; 72 73static struct i2c_driver driver; 74static struct i2c_client client_template; 75 76/* ---------------------------------------------------------------------- */ 77 78// 79// TDA defines 80// 81 82//// first reg (b) 83#define cVideoTrapBypassOFF 0x00 // bit b0 84#define cVideoTrapBypassON 0x01 // bit b0 85 86#define cAutoMuteFmInactive 0x00 // bit b1 87#define cAutoMuteFmActive 0x02 // bit b1 88 89#define cIntercarrier 0x00 // bit b2 90#define cQSS 0x04 // bit b2 91 92#define cPositiveAmTV 0x00 // bit b3:4 93#define cFmRadio 0x08 // bit b3:4 94#define cNegativeFmTV 0x10 // bit b3:4 95 96 97#define cForcedMuteAudioON 0x20 // bit b5 98#define cForcedMuteAudioOFF 0x00 // bit b5 99 100#define cOutputPort1Active 0x00 // bit b6 101#define cOutputPort1Inactive 0x40 // bit b6 102 103#define cOutputPort2Active 0x00 // bit b7 104#define cOutputPort2Inactive 0x80 // bit b7 105 106 107//// second reg (c) 108#define cDeemphasisOFF 0x00 // bit c5 109#define cDeemphasisON 0x20 // bit c5 110 111#define cDeemphasis75 0x00 // bit c6 112#define cDeemphasis50 0x40 // bit c6 113 114#define cAudioGain0 0x00 // bit c7 115#define cAudioGain6 0x80 // bit c7 116 117#define cTopMask 0x1f // bit c0:4 118#define cTopPalSecamDefault 0x14 // bit c0:4 119#define cTopNtscRadioDefault 0x10 // bit c0:4 120 121//// third reg (e) 122#define cAudioIF_4_5 0x00 // bit e0:1 123#define cAudioIF_5_5 0x01 // bit e0:1 124#define cAudioIF_6_0 0x02 // bit e0:1 125#define cAudioIF_6_5 0x03 // bit e0:1 126 127 128#define cVideoIF_58_75 0x00 // bit e2:4 129#define cVideoIF_45_75 0x04 // bit e2:4 130#define cVideoIF_38_90 0x08 // bit e2:4 131#define cVideoIF_38_00 0x0C // bit e2:4 132#define cVideoIF_33_90 0x10 // bit e2:4 133#define cVideoIF_33_40 0x14 // bit e2:4 134#define cRadioIF_45_75 0x18 // bit e2:4 135#define cRadioIF_38_90 0x1C // bit e2:4 136 137 138#define cTunerGainNormal 0x00 // bit e5 139#define cTunerGainLow 0x20 // bit e5 140 141#define cGating_18 0x00 // bit e6 142#define cGating_36 0x40 // bit e6 143 144#define cAgcOutON 0x80 // bit e7 145#define cAgcOutOFF 0x00 // bit e7 146 147/* ---------------------------------------------------------------------- */ 148 149static struct tvnorm tvnorms[] = { 150 { 151 .std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N, 152 .name = "PAL-BGHN", 153 .b = ( cNegativeFmTV | 154 cQSS ), 155 .c = ( cDeemphasisON | 156 cDeemphasis50 | 157 cTopPalSecamDefault), 158 .e = ( cGating_36 | 159 cAudioIF_5_5 | 160 cVideoIF_38_90 ), 161 },{ 162 .std = V4L2_STD_PAL_I, 163 .name = "PAL-I", 164 .b = ( cNegativeFmTV | 165 cQSS ), 166 .c = ( cDeemphasisON | 167 cDeemphasis50 | 168 cTopPalSecamDefault), 169 .e = ( cGating_36 | 170 cAudioIF_6_0 | 171 cVideoIF_38_90 ), 172 },{ 173 .std = V4L2_STD_PAL_DK, 174 .name = "PAL-DK", 175 .b = ( cNegativeFmTV | 176 cQSS ), 177 .c = ( cDeemphasisON | 178 cDeemphasis50 | 179 cTopPalSecamDefault), 180 .e = ( cGating_36 | 181 cAudioIF_6_5 | 182 cVideoIF_38_90 ), 183 },{ 184 .std = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc, 185 .name = "PAL-M/Nc", 186 .b = ( cNegativeFmTV | 187 cQSS ), 188 .c = ( cDeemphasisON | 189 cDeemphasis75 | 190 cTopNtscRadioDefault), 191 .e = ( cGating_36 | 192 cAudioIF_4_5 | 193 cVideoIF_45_75 ), 194 },{ 195 .std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, 196 .name = "SECAM-BGH", 197 .b = ( cPositiveAmTV | 198 cQSS ), 199 .c = ( cTopPalSecamDefault), 200 .e = ( cGating_36 | 201 cAudioIF_5_5 | 202 cVideoIF_38_90 ), 203 },{ 204 .std = V4L2_STD_SECAM_L, 205 .name = "SECAM-L", 206 .b = ( cPositiveAmTV | 207 cQSS ), 208 .c = ( cTopPalSecamDefault), 209 .e = ( cGating_36 | 210 cAudioIF_6_5 | 211 cVideoIF_38_90 ), 212 },{ 213 .std = V4L2_STD_SECAM_LC, 214 .name = "SECAM-L'", 215 .b = ( cOutputPort2Inactive | 216 cPositiveAmTV | 217 cQSS ), 218 .c = ( cTopPalSecamDefault), 219 .e = ( cGating_36 | 220 cAudioIF_6_5 | 221 cVideoIF_33_90 ), 222 },{ 223 .std = V4L2_STD_SECAM_DK, 224 .name = "SECAM-DK", 225 .b = ( cNegativeFmTV | 226 cQSS ), 227 .c = ( cDeemphasisON | 228 cDeemphasis50 | 229 cTopPalSecamDefault), 230 .e = ( cGating_36 | 231 cAudioIF_6_5 | 232 cVideoIF_38_90 ), 233 },{ 234 .std = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR, 235 .name = "NTSC-M", 236 .b = ( cNegativeFmTV | 237 cQSS ), 238 .c = ( cDeemphasisON | 239 cDeemphasis75 | 240 cTopNtscRadioDefault), 241 .e = ( cGating_36 | 242 cAudioIF_4_5 | 243 cVideoIF_45_75 ), 244 },{ 245 .std = V4L2_STD_NTSC_M_JP, 246 .name = "NTSC-M-JP", 247 .b = ( cNegativeFmTV | 248 cQSS ), 249 .c = ( cDeemphasisON | 250 cDeemphasis50 | 251 cTopNtscRadioDefault), 252 .e = ( cGating_36 | 253 cAudioIF_4_5 | 254 cVideoIF_58_75 ), 255 } 256}; 257 258static struct tvnorm radio_stereo = { 259 .name = "Radio Stereo", 260 .b = ( cFmRadio | 261 cQSS ), 262 .c = ( cDeemphasisOFF | 263 cAudioGain6 | 264 cTopNtscRadioDefault), 265 .e = ( cTunerGainLow | 266 cAudioIF_5_5 | 267 cRadioIF_38_90 ), 268}; 269 270static struct tvnorm radio_mono = { 271 .name = "Radio Mono", 272 .b = ( cFmRadio | 273 cQSS ), 274 .c = ( cDeemphasisON | 275 cDeemphasis75 | 276 cTopNtscRadioDefault), 277 .e = ( cTunerGainLow | 278 cAudioIF_5_5 | 279 cRadioIF_38_90 ), 280}; 281 282/* ---------------------------------------------------------------------- */ 283 284static void dump_read_message(struct tda9887 *t, unsigned char *buf) 285{ 286 static char *afc[16] = { 287 "- 12.5 kHz", 288 "- 37.5 kHz", 289 "- 62.5 kHz", 290 "- 87.5 kHz", 291 "-112.5 kHz", 292 "-137.5 kHz", 293 "-162.5 kHz", 294 "-187.5 kHz [min]", 295 "+187.5 kHz [max]", 296 "+162.5 kHz", 297 "+137.5 kHz", 298 "+112.5 kHz", 299 "+ 87.5 kHz", 300 "+ 62.5 kHz", 301 "+ 37.5 kHz", 302 "+ 12.5 kHz", 303 }; 304 tda9887_info("read: 0x%2x\n", buf[0]); 305 tda9887_info(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no"); 306 tda9887_info(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]); 307 tda9887_info(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low"); 308 tda9887_info(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out"); 309 tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low"); 310} 311 312static void dump_write_message(struct tda9887 *t, unsigned char *buf) 313{ 314 static char *sound[4] = { 315 "AM/TV", 316 "FM/radio", 317 "FM/TV", 318 "FM/radio" 319 }; 320 static char *adjust[32] = { 321 "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9", 322 "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1", 323 "0", "+1", "+2", "+3", "+4", "+5", "+6", "+7", 324 "+8", "+9", "+10", "+11", "+12", "+13", "+14", "+15" 325 }; 326 static char *deemph[4] = { 327 "no", "no", "75", "50" 328 }; 329 static char *carrier[4] = { 330 "4.5 MHz", 331 "5.5 MHz", 332 "6.0 MHz", 333 "6.5 MHz / AM" 334 }; 335 static char *vif[8] = { 336 "58.75 MHz", 337 "45.75 MHz", 338 "38.9 MHz", 339 "38.0 MHz", 340 "33.9 MHz", 341 "33.4 MHz", 342 "45.75 MHz + pin13", 343 "38.9 MHz + pin13", 344 }; 345 static char *rif[4] = { 346 "44 MHz", 347 "52 MHz", 348 "52 MHz", 349 "44 MHz", 350 }; 351 352 tda9887_info("write: byte B 0x%02x\n",buf[1]); 353 tda9887_info(" B0 video mode : %s\n", 354 (buf[1] & 0x01) ? "video trap" : "sound trap"); 355 tda9887_info(" B1 auto mute fm : %s\n", 356 (buf[1] & 0x02) ? "yes" : "no"); 357 tda9887_info(" B2 carrier mode : %s\n", 358 (buf[1] & 0x04) ? "QSS" : "Intercarrier"); 359 tda9887_info(" B3-4 tv sound/radio : %s\n", 360 sound[(buf[1] & 0x18) >> 3]); 361 tda9887_info(" B5 force mute audio: %s\n", 362 (buf[1] & 0x20) ? "yes" : "no"); 363 tda9887_info(" B6 output port 1 : %s\n", 364 (buf[1] & 0x40) ? "high (inactive)" : "low (active)"); 365 tda9887_info(" B7 output port 2 : %s\n", 366 (buf[1] & 0x80) ? "high (inactive)" : "low (active)"); 367 368 tda9887_info("write: byte C 0x%02x\n",buf[2]); 369 tda9887_info(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]); 370 tda9887_info(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]); 371 tda9887_info(" C7 audio gain : %s\n", 372 (buf[2] & 0x80) ? "-6" : "0"); 373 374 tda9887_info("write: byte E 0x%02x\n",buf[3]); 375 tda9887_info(" E0-1 sound carrier : %s\n", 376 carrier[(buf[3] & 0x03)]); 377 tda9887_info(" E6 l pll gating : %s\n", 378 (buf[3] & 0x40) ? "36" : "13"); 379 380 if (buf[1] & 0x08) { 381 /* radio */ 382 tda9887_info(" E2-4 video if : %s\n", 383 rif[(buf[3] & 0x0c) >> 2]); 384 tda9887_info(" E7 vif agc output : %s\n", 385 (buf[3] & 0x80) 386 ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio") 387 : "fm radio carrier afc"); 388 } else { 389 /* video */ 390 tda9887_info(" E2-4 video if : %s\n", 391 vif[(buf[3] & 0x1c) >> 2]); 392 tda9887_info(" E5 tuner gain : %s\n", 393 (buf[3] & 0x80) 394 ? ((buf[3] & 0x20) ? "external" : "normal") 395 : ((buf[3] & 0x20) ? "minimum" : "normal")); 396 tda9887_info(" E7 vif agc output : %s\n", 397 (buf[3] & 0x80) 398 ? ((buf[3] & 0x20) 399 ? "pin3 port, pin22 vif agc out" 400 : "pin22 port, pin3 vif acg ext in") 401 : "pin3+pin22 port"); 402 } 403 tda9887_info("--\n"); 404} 405 406/* ---------------------------------------------------------------------- */ 407 408static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) 409{ 410 struct tvnorm *norm = NULL; 411 int i; 412 413 if (t->mode == T_RADIO) { 414 if (t->radio_mode == V4L2_TUNER_MODE_MONO) 415 norm = &radio_mono; 416 else 417 norm = &radio_stereo; 418 } else { 419 for (i = 0; i < ARRAY_SIZE(tvnorms); i++) { 420 if (tvnorms[i].std & t->std) { 421 norm = tvnorms+i; 422 break; 423 } 424 } 425 } 426 if (NULL == norm) { 427 tda9887_dbg("Unsupported tvnorm entry - audio muted\n"); 428 return -1; 429 } 430 431 tda9887_dbg("configure for: %s\n",norm->name); 432 buf[1] = norm->b; 433 buf[2] = norm->c; 434 buf[3] = norm->e; 435 return 0; 436} 437 438static unsigned int port1 = UNSET; 439static unsigned int port2 = UNSET; 440static unsigned int qss = UNSET; 441static unsigned int adjust = UNSET; 442 443module_param(port1, int, 0644); 444module_param(port2, int, 0644); 445module_param(qss, int, 0644); 446module_param(adjust, int, 0644); 447 448static int tda9887_set_insmod(struct tda9887 *t, char *buf) 449{ 450 if (UNSET != port1) { 451 if (port1) 452 buf[1] |= cOutputPort1Inactive; 453 else 454 buf[1] &= ~cOutputPort1Inactive; 455 } 456 if (UNSET != port2) { 457 if (port2) 458 buf[1] |= cOutputPort2Inactive; 459 else 460 buf[1] &= ~cOutputPort2Inactive; 461 } 462 463 if (UNSET != qss) { 464 if (qss) 465 buf[1] |= cQSS; 466 else 467 buf[1] &= ~cQSS; 468 } 469 470 if (adjust >= 0x00 && adjust < 0x20) { 471 buf[2] &= ~cTopMask; 472 buf[2] |= adjust; 473 } 474 return 0; 475} 476 477static int tda9887_set_config(struct tda9887 *t, char *buf) 478{ 479 if (t->config & TDA9887_PORT1_ACTIVE) 480 buf[1] &= ~cOutputPort1Inactive; 481 if (t->config & TDA9887_PORT1_INACTIVE) 482 buf[1] |= cOutputPort1Inactive; 483 if (t->config & TDA9887_PORT2_ACTIVE) 484 buf[1] &= ~cOutputPort2Inactive; 485 if (t->config & TDA9887_PORT2_INACTIVE) 486 buf[1] |= cOutputPort2Inactive; 487 488 if (t->config & TDA9887_QSS) 489 buf[1] |= cQSS; 490 if (t->config & TDA9887_INTERCARRIER) 491 buf[1] &= ~cQSS; 492 493 if (t->config & TDA9887_AUTOMUTE) 494 buf[1] |= cAutoMuteFmActive; 495 if (t->config & TDA9887_DEEMPHASIS_MASK) { 496 buf[2] &= ~0x60; 497 switch (t->config & TDA9887_DEEMPHASIS_MASK) { 498 case TDA9887_DEEMPHASIS_NONE: 499 buf[2] |= cDeemphasisOFF; 500 break; 501 case TDA9887_DEEMPHASIS_50: 502 buf[2] |= cDeemphasisON | cDeemphasis50; 503 break; 504 case TDA9887_DEEMPHASIS_75: 505 buf[2] |= cDeemphasisON | cDeemphasis75; 506 break; 507 } 508 } 509 if (t->config & TDA9887_TOP_SET) { 510 buf[2] &= ~cTopMask; 511 buf[2] |= (t->config >> 8) & cTopMask; 512 } 513 if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) 514 buf[1] &= ~cQSS; 515 return 0; 516} 517 518/* ---------------------------------------------------------------------- */ 519 520static char pal[] = "--"; 521static char secam[] = "--"; 522static char ntsc[] = "-"; 523 524module_param_string(pal, pal, sizeof(pal), 0644); 525module_param_string(secam, secam, sizeof(secam), 0644); 526module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); 527 528static int tda9887_fixup_std(struct tda9887 *t) 529{ 530 /* get more precise norm info from insmod option */ 531 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) { 532 switch (pal[0]) { 533 case 'b': 534 case 'B': 535 case 'g': 536 case 'G': 537 case 'h': 538 case 'H': 539 case 'n': 540 case 'N': 541 if (pal[1] == 'c' || pal[1] == 'C') { 542 tda9887_dbg("insmod fixup: PAL => PAL-Nc\n"); 543 t->std = V4L2_STD_PAL_Nc; 544 } else { 545 tda9887_dbg("insmod fixup: PAL => PAL-BGHN\n"); 546 t->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N; 547 } 548 break; 549 case 'i': 550 case 'I': 551 tda9887_dbg("insmod fixup: PAL => PAL-I\n"); 552 t->std = V4L2_STD_PAL_I; 553 break; 554 case 'd': 555 case 'D': 556 case 'k': 557 case 'K': 558 tda9887_dbg("insmod fixup: PAL => PAL-DK\n"); 559 t->std = V4L2_STD_PAL_DK; 560 break; 561 case 'm': 562 case 'M': 563 tda9887_dbg("insmod fixup: PAL => PAL-M\n"); 564 t->std = V4L2_STD_PAL_M; 565 break; 566 case '-': 567 /* default parameter, do nothing */ 568 break; 569 default: 570 tda9887_info("pal= argument not recognised\n"); 571 break; 572 } 573 } 574 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { 575 switch (secam[0]) { 576 case 'b': 577 case 'B': 578 case 'g': 579 case 'G': 580 case 'h': 581 case 'H': 582 tda9887_dbg("insmod fixup: SECAM => SECAM-BGH\n"); 583 t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; 584 break; 585 case 'd': 586 case 'D': 587 case 'k': 588 case 'K': 589 tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n"); 590 t->std = V4L2_STD_SECAM_DK; 591 break; 592 case 'l': 593 case 'L': 594 if (secam[1] == 'c' || secam[1] == 'C') { 595 tda9887_dbg("insmod fixup: SECAM => SECAM-L'\n"); 596 t->std = V4L2_STD_SECAM_LC; 597 } else { 598 tda9887_dbg("insmod fixup: SECAM => SECAM-L\n"); 599 t->std = V4L2_STD_SECAM_L; 600 } 601 break; 602 case '-': 603 /* default parameter, do nothing */ 604 break; 605 default: 606 tda9887_info("secam= argument not recognised\n"); 607 break; 608 } 609 } 610 if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { 611 switch (ntsc[0]) { 612 case 'm': 613 case 'M': 614 tda9887_dbg("insmod fixup: NTSC => NTSC-M\n"); 615 t->std = V4L2_STD_NTSC_M; 616 break; 617 case 'j': 618 case 'J': 619 tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); 620 t->std = V4L2_STD_NTSC_M_JP; 621 break; 622 case 'k': 623 case 'K': 624 tda9887_dbg("insmod fixup: NTSC => NTSC_M_KR\n"); 625 t->std = V4L2_STD_NTSC_M_KR; 626 break; 627 case '-': 628 /* default parameter, do nothing */ 629 break; 630 default: 631 tda9887_info("ntsc= argument not recognised\n"); 632 break; 633 } 634 } 635 return 0; 636} 637 638static int tda9887_status(struct tda9887 *t) 639{ 640 unsigned char buf[1]; 641 int rc; 642 643 memset(buf,0,sizeof(buf)); 644 if (1 != (rc = i2c_master_recv(&t->client,buf,1))) 645 tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc); 646 dump_read_message(t, buf); 647 return 0; 648} 649 650static int tda9887_configure(struct tda9887 *t) 651{ 652 int rc; 653 654 memset(t->data,0,sizeof(t->data)); 655 tda9887_set_tvnorm(t,t->data); 656 657 /* A note on the port settings: 658 These settings tend to depend on the specifics of the board. 659 By default they are set to inactive (bit value 1) by this driver, 660 overwriting any changes made by the tvnorm. This means that it 661 is the responsibility of the module using the tda9887 to set 662 these values in case of changes in the tvnorm. 663 In many cases port 2 should be made active (0) when selecting 664 SECAM-L, and port 2 should remain inactive (1) for SECAM-L'. 665 666 For the other standards the tda9887 application note says that 667 the ports should be set to active (0), but, again, that may 668 differ depending on the precise hardware configuration. 669 */ 670 t->data[1] |= cOutputPort1Inactive; 671 t->data[1] |= cOutputPort2Inactive; 672 673 tda9887_set_config(t,t->data); 674 tda9887_set_insmod(t,t->data); 675 676 if (t->mode == T_STANDBY) { 677 t->data[1] |= cForcedMuteAudioON; 678 } 679 680 tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", 681 t->data[1],t->data[2],t->data[3]); 682 if (debug > 1) 683 dump_write_message(t, t->data); 684 685 if (4 != (rc = i2c_master_send(&t->client,t->data,4))) 686 tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc); 687 688 if (debug > 2) { 689 msleep_interruptible(1000); 690 tda9887_status(t); 691 } 692 return 0; 693} 694 695/* ---------------------------------------------------------------------- */ 696 697static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) 698{ 699 struct tda9887 *t; 700 701 client_template.adapter = adap; 702 client_template.addr = addr; 703 704 if (NULL == (t = kzalloc(sizeof(*t), GFP_KERNEL))) 705 return -ENOMEM; 706 707 t->client = client_template; 708 t->std = 0; 709 t->radio_mode = V4L2_TUNER_MODE_STEREO; 710 711 tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name); 712 713 i2c_set_clientdata(&t->client, t); 714 i2c_attach_client(&t->client); 715 716 return 0; 717} 718 719static int tda9887_probe(struct i2c_adapter *adap) 720{ 721 if (adap->class & I2C_CLASS_TV_ANALOG) 722 return i2c_probe(adap, &addr_data, tda9887_attach); 723 return 0; 724} 725 726static int tda9887_detach(struct i2c_client *client) 727{ 728 struct tda9887 *t = i2c_get_clientdata(client); 729 730 i2c_detach_client(client); 731 kfree(t); 732 return 0; 733} 734 735#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ 736 tda9887_info("switching to v4l2\n"); \ 737 t->using_v4l2 = 1; 738#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \ 739 tda9887_info("ignore v4l1 call\n"); \ 740 return 0; } 741 742static int 743tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) 744{ 745 struct tda9887 *t = i2c_get_clientdata(client); 746 747 switch (cmd) { 748 749 /* --- configuration --- */ 750 case AUDC_SET_RADIO: 751 { 752 t->mode = T_RADIO; 753 tda9887_configure(t); 754 break; 755 } 756 case TUNER_SET_STANDBY: 757 { 758 t->mode = T_STANDBY; 759 tda9887_configure(t); 760 break; 761 } 762 case TDA9887_SET_CONFIG: 763 { 764 int *i = arg; 765 766 t->config = *i; 767 tda9887_configure(t); 768 break; 769 } 770 /* --- v4l ioctls --- */ 771 /* take care: bttv does userspace copying, we'll get a 772 kernel pointer here... */ 773 case VIDIOCSCHAN: 774 { 775 static const v4l2_std_id map[] = { 776 [ VIDEO_MODE_PAL ] = V4L2_STD_PAL, 777 [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M, 778 [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM, 779 [ 4 /* bttv */ ] = V4L2_STD_PAL_M, 780 [ 5 /* bttv */ ] = V4L2_STD_PAL_N, 781 [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP, 782 }; 783 struct video_channel *vc = arg; 784 785 CHECK_V4L2; 786 t->mode = T_ANALOG_TV; 787 if (vc->norm < ARRAY_SIZE(map)) 788 t->std = map[vc->norm]; 789 tda9887_fixup_std(t); 790 tda9887_configure(t); 791 break; 792 } 793 case VIDIOC_S_STD: 794 { 795 v4l2_std_id *id = arg; 796 797 SWITCH_V4L2; 798 t->mode = T_ANALOG_TV; 799 t->std = *id; 800 tda9887_fixup_std(t); 801 tda9887_configure(t); 802 break; 803 } 804 case VIDIOC_S_FREQUENCY: 805 { 806 struct v4l2_frequency *f = arg; 807 808 SWITCH_V4L2; 809 if (V4L2_TUNER_ANALOG_TV == f->type) { 810 if (t->mode == T_ANALOG_TV) 811 return 0; 812 t->mode = T_ANALOG_TV; 813 } 814 if (V4L2_TUNER_RADIO == f->type) { 815 if (t->mode == T_RADIO) 816 return 0; 817 t->mode = T_RADIO; 818 } 819 tda9887_configure(t); 820 break; 821 } 822 case VIDIOC_G_TUNER: 823 { 824 static int AFC_BITS_2_kHz[] = { 825 -12500, -37500, -62500, -97500, 826 -112500, -137500, -162500, -187500, 827 187500, 162500, 137500, 112500, 828 97500 , 62500, 37500 , 12500 829 }; 830 struct v4l2_tuner* tuner = arg; 831 832 if (t->mode == T_RADIO) { 833 __u8 reg = 0; 834 tuner->afc=0; 835 if (1 == i2c_master_recv(&t->client,&reg,1)) 836 tuner->afc = AFC_BITS_2_kHz[(reg>>1)&0x0f]; 837 } 838 break; 839 } 840 case VIDIOC_S_TUNER: 841 { 842 struct v4l2_tuner* tuner = arg; 843 844 if (t->mode == T_RADIO) { 845 t->radio_mode = tuner->audmode; 846 tda9887_configure (t); 847 } 848 break; 849 } 850 case VIDIOC_LOG_STATUS: 851 { 852 tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1], t->data[2], t->data[3]); 853 break; 854 } 855 default: 856 /* nothing */ 857 break; 858 } 859 return 0; 860} 861 862static int tda9887_suspend(struct device * dev, pm_message_t state) 863{ 864 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 865 struct tda9887 *t = i2c_get_clientdata(c); 866 867 tda9887_dbg("suspend\n"); 868 return 0; 869} 870 871static int tda9887_resume(struct device * dev) 872{ 873 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 874 struct tda9887 *t = i2c_get_clientdata(c); 875 876 tda9887_dbg("resume\n"); 877 tda9887_configure(t); 878 return 0; 879} 880 881/* ----------------------------------------------------------------------- */ 882 883static struct i2c_driver driver = { 884 .id = I2C_DRIVERID_TDA9887, 885 .attach_adapter = tda9887_probe, 886 .detach_client = tda9887_detach, 887 .command = tda9887_command, 888 .driver = { 889 .name = "tda9887", 890 .suspend = tda9887_suspend, 891 .resume = tda9887_resume, 892 }, 893}; 894static struct i2c_client client_template = 895{ 896 .name = "tda9887", 897 .driver = &driver, 898}; 899 900static int __init tda9887_init_module(void) 901{ 902 return i2c_add_driver(&driver); 903} 904 905static void __exit tda9887_cleanup_module(void) 906{ 907 i2c_del_driver(&driver); 908} 909 910module_init(tda9887_init_module); 911module_exit(tda9887_cleanup_module); 912 913/* 914 * Overrides for Emacs so that we follow Linus's tabbing style. 915 * --------------------------------------------------------------------------- 916 * Local variables: 917 * c-basic-offset: 8 918 * End: 919 */