1 /* 2 * i2c tv tuner chip device driver 3 * controls microtune tuners, mt2032 + mt2050 at the moment. 4 * 5 * This "mt20xx" module was split apart from the original "tuner" module. 6 */ 7 #include <linux/delay.h> 8 #include <linux/i2c.h> 9 #include <linux/slab.h> 10 #include <linux/videodev2.h> 11 #include "tuner-i2c.h" 12 #include "mt20xx.h" 13 14 static int debug; 15 module_param(debug, int, 0644); 16 MODULE_PARM_DESC(debug, "enable verbose debug messages"); 17 18 /* ---------------------------------------------------------------------- */ 19 20 static unsigned int optimize_vco = 1; 21 module_param(optimize_vco, int, 0644); 22 23 static unsigned int tv_antenna = 1; 24 module_param(tv_antenna, int, 0644); 25 26 static unsigned int radio_antenna; 27 module_param(radio_antenna, int, 0644); 28 29 /* ---------------------------------------------------------------------- */ 30 31 #define MT2032 0x04 32 #define MT2030 0x06 33 #define MT2040 0x07 34 #define MT2050 0x42 35 36 static char *microtune_part[] = { 37 [ MT2030 ] = "MT2030", 38 [ MT2032 ] = "MT2032", 39 [ MT2040 ] = "MT2040", 40 [ MT2050 ] = "MT2050", 41 }; 42 43 struct microtune_priv { 44 struct tuner_i2c_props i2c_props; 45 46 unsigned int xogc; 47 //unsigned int radio_if2; 48 49 u32 frequency; 50 }; 51 52 static int microtune_release(struct dvb_frontend *fe) 53 { 54 kfree(fe->tuner_priv); 55 fe->tuner_priv = NULL; 56 57 return 0; 58 } 59 60 static int microtune_get_frequency(struct dvb_frontend *fe, u32 *frequency) 61 { 62 struct microtune_priv *priv = fe->tuner_priv; 63 *frequency = priv->frequency; 64 return 0; 65 } 66 67 // IsSpurInBand()? 68 static int mt2032_spurcheck(struct dvb_frontend *fe, 69 int f1, int f2, int spectrum_from,int spectrum_to) 70 { 71 struct microtune_priv *priv = fe->tuner_priv; 72 int n1=1,n2,f; 73 74 f1=f1/1000; //scale to kHz to avoid 32bit overflows 75 f2=f2/1000; 76 spectrum_from/=1000; 77 spectrum_to/=1000; 78 79 tuner_dbg("spurcheck f1=%d f2=%d from=%d to=%d\n", 80 f1,f2,spectrum_from,spectrum_to); 81 82 do { 83 n2=-n1; 84 f=n1*(f1-f2); 85 do { 86 n2--; 87 f=f-f2; 88 tuner_dbg("spurtest n1=%d n2=%d ftest=%d\n",n1,n2,f); 89 90 if( (f>spectrum_from) && (f<spectrum_to)) 91 tuner_dbg("mt2032 spurcheck triggered: %d\n",n1); 92 } while ( (f>(f2-spectrum_to)) || (n2>-5)); 93 n1++; 94 } while (n1<5); 95 96 return 1; 97 } 98 99 static int mt2032_compute_freq(struct dvb_frontend *fe, 100 unsigned int rfin, 101 unsigned int if1, unsigned int if2, 102 unsigned int spectrum_from, 103 unsigned int spectrum_to, 104 unsigned char *buf, 105 int *ret_sel, 106 unsigned int xogc) //all in Hz 107 { 108 struct microtune_priv *priv = fe->tuner_priv; 109 unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1, 110 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq; 111 112 fref= 5250 *1000; //5.25MHz 113 desired_lo1=rfin+if1; 114 115 lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000); 116 lo1n=lo1/8; 117 lo1a=lo1-(lo1n*8); 118 119 s=rfin/1000/1000+1090; 120 121 if(optimize_vco) { 122 if(s>1890) sel=0; 123 else if(s>1720) sel=1; 124 else if(s>1530) sel=2; 125 else if(s>1370) sel=3; 126 else sel=4; // >1090 127 } 128 else { 129 if(s>1790) sel=0; // <1958 130 else if(s>1617) sel=1; 131 else if(s>1449) sel=2; 132 else if(s>1291) sel=3; 133 else sel=4; // >1090 134 } 135 *ret_sel=sel; 136 137 lo1freq=(lo1a+8*lo1n)*fref; 138 139 tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n", 140 rfin,lo1,lo1n,lo1a,sel,lo1freq); 141 142 desired_lo2=lo1freq-rfin-if2; 143 lo2=(desired_lo2)/fref; 144 lo2n=lo2/8; 145 lo2a=lo2-(lo2n*8); 146 lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith 147 lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000; 148 149 tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n", 150 rfin,lo2,lo2n,lo2a,lo2num,lo2freq); 151 152 if (lo1a > 7 || lo1n < 17 || lo1n > 48 || lo2a > 7 || lo2n < 17 || 153 lo2n > 30) { 154 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n", 155 lo1a, lo1n, lo2a,lo2n); 156 return(-1); 157 } 158 159 mt2032_spurcheck(fe, lo1freq, desired_lo2, spectrum_from, spectrum_to); 160 // should recalculate lo1 (one step up/down) 161 162 // set up MT2032 register map for transfer over i2c 163 buf[0]=lo1n-1; 164 buf[1]=lo1a | (sel<<4); 165 buf[2]=0x86; // LOGC 166 buf[3]=0x0f; //reserved 167 buf[4]=0x1f; 168 buf[5]=(lo2n-1) | (lo2a<<5); 169 if(rfin >400*1000*1000) 170 buf[6]=0xe4; 171 else 172 buf[6]=0xf4; // set PKEN per rev 1.2 173 buf[7]=8+xogc; 174 buf[8]=0xc3; //reserved 175 buf[9]=0x4e; //reserved 176 buf[10]=0xec; //reserved 177 buf[11]=(lo2num&0xff); 178 buf[12]=(lo2num>>8) |0x80; // Lo2RST 179 180 return 0; 181 } 182 183 static int mt2032_check_lo_lock(struct dvb_frontend *fe) 184 { 185 struct microtune_priv *priv = fe->tuner_priv; 186 int try,lock=0; 187 unsigned char buf[2]; 188 189 for(try=0;try<10;try++) { 190 buf[0]=0x0e; 191 tuner_i2c_xfer_send(&priv->i2c_props,buf,1); 192 tuner_i2c_xfer_recv(&priv->i2c_props,buf,1); 193 tuner_dbg("mt2032 Reg.E=0x%02x\n",buf[0]); 194 lock=buf[0] &0x06; 195 196 if (lock==6) 197 break; 198 199 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]); 200 udelay(1000); 201 } 202 return lock; 203 } 204 205 static int mt2032_optimize_vco(struct dvb_frontend *fe,int sel,int lock) 206 { 207 struct microtune_priv *priv = fe->tuner_priv; 208 unsigned char buf[2]; 209 int tad1; 210 211 buf[0]=0x0f; 212 tuner_i2c_xfer_send(&priv->i2c_props,buf,1); 213 tuner_i2c_xfer_recv(&priv->i2c_props,buf,1); 214 tuner_dbg("mt2032 Reg.F=0x%02x\n",buf[0]); 215 tad1=buf[0]&0x07; 216 217 if(tad1 ==0) return lock; 218 if(tad1 ==1) return lock; 219 220 if(tad1==2) { 221 if(sel==0) 222 return lock; 223 else sel--; 224 } 225 else { 226 if(sel<4) 227 sel++; 228 else 229 return lock; 230 } 231 232 tuner_dbg("mt2032 optimize_vco: sel=%d\n",sel); 233 234 buf[0]=0x0f; 235 buf[1]=sel; 236 tuner_i2c_xfer_send(&priv->i2c_props,buf,2); 237 lock=mt2032_check_lo_lock(fe); 238 return lock; 239 } 240 241 242 static void mt2032_set_if_freq(struct dvb_frontend *fe, unsigned int rfin, 243 unsigned int if1, unsigned int if2, 244 unsigned int from, unsigned int to) 245 { 246 unsigned char buf[21]; 247 int lint_try,ret,sel,lock=0; 248 struct microtune_priv *priv = fe->tuner_priv; 249 250 tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n", 251 rfin,if1,if2,from,to); 252 253 buf[0]=0; 254 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,1); 255 tuner_i2c_xfer_recv(&priv->i2c_props,buf,21); 256 257 buf[0]=0; 258 ret=mt2032_compute_freq(fe,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc); 259 if (ret<0) 260 return; 261 262 // send only the relevant registers per Rev. 1.2 263 buf[0]=0; 264 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,4); 265 buf[5]=5; 266 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,4); 267 buf[11]=11; 268 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+11,3); 269 if(ret!=3) 270 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret); 271 272 // wait for PLLs to lock (per manual), retry LINT if not. 273 for(lint_try=0; lint_try<2; lint_try++) { 274 lock=mt2032_check_lo_lock(fe); 275 276 if(optimize_vco) 277 lock=mt2032_optimize_vco(fe,sel,lock); 278 if(lock==6) break; 279 280 tuner_dbg("mt2032: re-init PLLs by LINT\n"); 281 buf[0]=7; 282 buf[1]=0x80 +8+priv->xogc; // set LINT to re-init PLLs 283 tuner_i2c_xfer_send(&priv->i2c_props,buf,2); 284 mdelay(10); 285 buf[1]=8+priv->xogc; 286 tuner_i2c_xfer_send(&priv->i2c_props,buf,2); 287 } 288 289 if (lock!=6) 290 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n"); 291 292 buf[0]=2; 293 buf[1]=0x20; // LOGC for optimal phase noise 294 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2); 295 if (ret!=2) 296 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret); 297 } 298 299 300 static int mt2032_set_tv_freq(struct dvb_frontend *fe, 301 struct analog_parameters *params) 302 { 303 int if2,from,to; 304 305 // signal bandwidth and picture carrier 306 if (params->std & V4L2_STD_525_60) { 307 // NTSC 308 from = 40750*1000; 309 to = 46750*1000; 310 if2 = 45750*1000; 311 } else { 312 // PAL 313 from = 32900*1000; 314 to = 39900*1000; 315 if2 = 38900*1000; 316 } 317 318 mt2032_set_if_freq(fe, params->frequency*62500, 319 1090*1000*1000, if2, from, to); 320 321 return 0; 322 } 323 324 static int mt2032_set_radio_freq(struct dvb_frontend *fe, 325 struct analog_parameters *params) 326 { 327 struct microtune_priv *priv = fe->tuner_priv; 328 int if2; 329 330 if (params->std & V4L2_STD_525_60) { 331 tuner_dbg("pinnacle ntsc\n"); 332 if2 = 41300 * 1000; 333 } else { 334 tuner_dbg("pinnacle pal\n"); 335 if2 = 33300 * 1000; 336 } 337 338 // per Manual for FM tuning: first if center freq. 1085 MHz 339 mt2032_set_if_freq(fe, params->frequency * 125 / 2, 340 1085*1000*1000,if2,if2,if2); 341 342 return 0; 343 } 344 345 static int mt2032_set_params(struct dvb_frontend *fe, 346 struct analog_parameters *params) 347 { 348 struct microtune_priv *priv = fe->tuner_priv; 349 int ret = -EINVAL; 350 351 switch (params->mode) { 352 case V4L2_TUNER_RADIO: 353 ret = mt2032_set_radio_freq(fe, params); 354 priv->frequency = params->frequency * 125 / 2; 355 break; 356 case V4L2_TUNER_ANALOG_TV: 357 case V4L2_TUNER_DIGITAL_TV: 358 ret = mt2032_set_tv_freq(fe, params); 359 priv->frequency = params->frequency * 62500; 360 break; 361 } 362 363 return ret; 364 } 365 366 static struct dvb_tuner_ops mt2032_tuner_ops = { 367 .set_analog_params = mt2032_set_params, 368 .release = microtune_release, 369 .get_frequency = microtune_get_frequency, 370 }; 371 372 // Initialization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001 373 static int mt2032_init(struct dvb_frontend *fe) 374 { 375 struct microtune_priv *priv = fe->tuner_priv; 376 unsigned char buf[21]; 377 int ret,xogc,xok=0; 378 379 // Initialize Registers per spec. 380 buf[1]=2; // Index to register 2 381 buf[2]=0xff; 382 buf[3]=0x0f; 383 buf[4]=0x1f; 384 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+1,4); 385 386 buf[5]=6; // Index register 6 387 buf[6]=0xe4; 388 buf[7]=0x8f; 389 buf[8]=0xc3; 390 buf[9]=0x4e; 391 buf[10]=0xec; 392 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,6); 393 394 buf[12]=13; // Index register 13 395 buf[13]=0x32; 396 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+12,2); 397 398 // Adjust XOGC (register 7), wait for XOK 399 xogc=7; 400 do { 401 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); 402 mdelay(10); 403 buf[0]=0x0e; 404 tuner_i2c_xfer_send(&priv->i2c_props,buf,1); 405 tuner_i2c_xfer_recv(&priv->i2c_props,buf,1); 406 xok=buf[0]&0x01; 407 tuner_dbg("mt2032: xok = 0x%02x\n",xok); 408 if (xok == 1) break; 409 410 xogc--; 411 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); 412 if (xogc == 3) { 413 xogc=4; // min. 4 per spec 414 break; 415 } 416 buf[0]=0x07; 417 buf[1]=0x88 + xogc; 418 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2); 419 if (ret!=2) 420 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret); 421 } while (xok != 1 ); 422 priv->xogc=xogc; 423 424 memcpy(&fe->ops.tuner_ops, &mt2032_tuner_ops, sizeof(struct dvb_tuner_ops)); 425 426 return(1); 427 } 428 429 static void mt2050_set_antenna(struct dvb_frontend *fe, unsigned char antenna) 430 { 431 struct microtune_priv *priv = fe->tuner_priv; 432 unsigned char buf[2]; 433 434 buf[0] = 6; 435 buf[1] = antenna ? 0x11 : 0x10; 436 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); 437 tuner_dbg("mt2050: enabled antenna connector %d\n", antenna); 438 } 439 440 static void mt2050_set_if_freq(struct dvb_frontend *fe,unsigned int freq, unsigned int if2) 441 { 442 struct microtune_priv *priv = fe->tuner_priv; 443 unsigned int if1=1218*1000*1000; 444 unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b; 445 int ret; 446 unsigned char buf[6]; 447 448 tuner_dbg("mt2050_set_if_freq freq=%d if1=%d if2=%d\n", 449 freq,if1,if2); 450 451 f_lo1=freq+if1; 452 f_lo1=(f_lo1/1000000)*1000000; 453 454 f_lo2=f_lo1-freq-if2; 455 f_lo2=(f_lo2/50000)*50000; 456 457 lo1=f_lo1/4000000; 458 lo2=f_lo2/4000000; 459 460 f_lo1_modulo= f_lo1-(lo1*4000000); 461 f_lo2_modulo= f_lo2-(lo2*4000000); 462 463 num1=4*f_lo1_modulo/4000000; 464 num2=4096*(f_lo2_modulo/1000)/4000; 465 466 // todo spurchecks 467 468 div1a=(lo1/12)-1; 469 div1b=lo1-(div1a+1)*12; 470 471 div2a=(lo2/8)-1; 472 div2b=lo2-(div2a+1)*8; 473 474 if (debug > 1) { 475 tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2); 476 tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n", 477 num1,num2,div1a,div1b,div2a,div2b); 478 } 479 480 buf[0]=1; 481 buf[1]= 4*div1b + num1; 482 if(freq<275*1000*1000) buf[1] = buf[1]|0x80; 483 484 buf[2]=div1a; 485 buf[3]=32*div2b + num2/256; 486 buf[4]=num2-(num2/256)*256; 487 buf[5]=div2a; 488 if(num2!=0) buf[5]=buf[5]|0x40; 489 490 if (debug > 1) { 491 int i; 492 tuner_dbg("bufs is: "); 493 for(i=0;i<6;i++) 494 printk("%x ",buf[i]); 495 printk("\n"); 496 } 497 498 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,6); 499 if (ret!=6) 500 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret); 501 } 502 503 static int mt2050_set_tv_freq(struct dvb_frontend *fe, 504 struct analog_parameters *params) 505 { 506 unsigned int if2; 507 508 if (params->std & V4L2_STD_525_60) { 509 // NTSC 510 if2 = 45750*1000; 511 } else { 512 // PAL 513 if2 = 38900*1000; 514 } 515 if (V4L2_TUNER_DIGITAL_TV == params->mode) { 516 // DVB (pinnacle 300i) 517 if2 = 36150*1000; 518 } 519 mt2050_set_if_freq(fe, params->frequency*62500, if2); 520 mt2050_set_antenna(fe, tv_antenna); 521 522 return 0; 523 } 524 525 static int mt2050_set_radio_freq(struct dvb_frontend *fe, 526 struct analog_parameters *params) 527 { 528 struct microtune_priv *priv = fe->tuner_priv; 529 int if2; 530 531 if (params->std & V4L2_STD_525_60) { 532 tuner_dbg("pinnacle ntsc\n"); 533 if2 = 41300 * 1000; 534 } else { 535 tuner_dbg("pinnacle pal\n"); 536 if2 = 33300 * 1000; 537 } 538 539 mt2050_set_if_freq(fe, params->frequency * 125 / 2, if2); 540 mt2050_set_antenna(fe, radio_antenna); 541 542 return 0; 543 } 544 545 static int mt2050_set_params(struct dvb_frontend *fe, 546 struct analog_parameters *params) 547 { 548 struct microtune_priv *priv = fe->tuner_priv; 549 int ret = -EINVAL; 550 551 switch (params->mode) { 552 case V4L2_TUNER_RADIO: 553 ret = mt2050_set_radio_freq(fe, params); 554 priv->frequency = params->frequency * 125 / 2; 555 break; 556 case V4L2_TUNER_ANALOG_TV: 557 case V4L2_TUNER_DIGITAL_TV: 558 ret = mt2050_set_tv_freq(fe, params); 559 priv->frequency = params->frequency * 62500; 560 break; 561 } 562 563 return ret; 564 } 565 566 static struct dvb_tuner_ops mt2050_tuner_ops = { 567 .set_analog_params = mt2050_set_params, 568 .release = microtune_release, 569 .get_frequency = microtune_get_frequency, 570 }; 571 572 static int mt2050_init(struct dvb_frontend *fe) 573 { 574 struct microtune_priv *priv = fe->tuner_priv; 575 unsigned char buf[2]; 576 577 buf[0] = 6; 578 buf[1] = 0x10; 579 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); /* power */ 580 581 buf[0] = 0x0f; 582 buf[1] = 0x0f; 583 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); /* m1lo */ 584 585 buf[0] = 0x0d; 586 tuner_i2c_xfer_send(&priv->i2c_props, buf, 1); 587 tuner_i2c_xfer_recv(&priv->i2c_props, buf, 1); 588 589 tuner_dbg("mt2050: sro is %x\n", buf[0]); 590 591 memcpy(&fe->ops.tuner_ops, &mt2050_tuner_ops, sizeof(struct dvb_tuner_ops)); 592 593 return 0; 594 } 595 596 struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, 597 struct i2c_adapter* i2c_adap, 598 u8 i2c_addr) 599 { 600 struct microtune_priv *priv = NULL; 601 char *name; 602 unsigned char buf[21]; 603 int company_code; 604 605 priv = kzalloc(sizeof(struct microtune_priv), GFP_KERNEL); 606 if (priv == NULL) 607 return NULL; 608 fe->tuner_priv = priv; 609 610 priv->i2c_props.addr = i2c_addr; 611 priv->i2c_props.adap = i2c_adap; 612 priv->i2c_props.name = "mt20xx"; 613 614 //priv->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ 615 616 memset(buf,0,sizeof(buf)); 617 618 name = "unknown"; 619 620 tuner_i2c_xfer_send(&priv->i2c_props,buf,1); 621 tuner_i2c_xfer_recv(&priv->i2c_props,buf,21); 622 if (debug) { 623 int i; 624 tuner_dbg("MT20xx hexdump:"); 625 for(i=0;i<21;i++) { 626 printk(" %02x",buf[i]); 627 if(((i+1)%8)==0) printk(" "); 628 } 629 printk("\n"); 630 } 631 company_code = buf[0x11] << 8 | buf[0x12]; 632 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n", 633 company_code,buf[0x13],buf[0x14]); 634 635 636 if (buf[0x13] < ARRAY_SIZE(microtune_part) && 637 NULL != microtune_part[buf[0x13]]) 638 name = microtune_part[buf[0x13]]; 639 switch (buf[0x13]) { 640 case MT2032: 641 mt2032_init(fe); 642 break; 643 case MT2050: 644 mt2050_init(fe); 645 break; 646 default: 647 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n", 648 name); 649 return NULL; 650 } 651 652 strlcpy(fe->ops.tuner_ops.info.name, name, 653 sizeof(fe->ops.tuner_ops.info.name)); 654 tuner_info("microtune %s found, OK\n",name); 655 return fe; 656 } 657 658 EXPORT_SYMBOL_GPL(microtune_attach); 659 660 MODULE_DESCRIPTION("Microtune tuner driver"); 661 MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); 662 MODULE_LICENSE("GPL"); 663 664 /* 665 * Overrides for Emacs so that we follow Linus's tabbing style. 666 * --------------------------------------------------------------------------- 667 * Local variables: 668 * c-basic-offset: 8 669 * End: 670 */ 671