1 /* 2 * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner. 3 * 4 * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of the 9 * License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * 21 * 22 * This code is more or less generated from another driver, please 23 * excuse some codingstyle oddities. 24 * 25 */ 26 27 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 28 29 #include <linux/kernel.h> 30 #include <linux/slab.h> 31 #include <linux/i2c.h> 32 #include <linux/mutex.h> 33 34 #include "dvb_frontend.h" 35 36 #include "dib0090.h" 37 #include "dibx000_common.h" 38 39 static int debug; 40 module_param(debug, int, 0644); 41 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); 42 43 #define dprintk(fmt, arg...) do { \ 44 if (debug) \ 45 printk(KERN_DEBUG pr_fmt("%s: " fmt), \ 46 __func__, ##arg); \ 47 } while (0) 48 49 #define CONFIG_SYS_DVBT 50 #define CONFIG_SYS_ISDBT 51 #define CONFIG_BAND_CBAND 52 #define CONFIG_BAND_VHF 53 #define CONFIG_BAND_UHF 54 #define CONFIG_DIB0090_USE_PWM_AGC 55 56 #define EN_LNA0 0x8000 57 #define EN_LNA1 0x4000 58 #define EN_LNA2 0x2000 59 #define EN_LNA3 0x1000 60 #define EN_MIX0 0x0800 61 #define EN_MIX1 0x0400 62 #define EN_MIX2 0x0200 63 #define EN_MIX3 0x0100 64 #define EN_IQADC 0x0040 65 #define EN_PLL 0x0020 66 #define EN_TX 0x0010 67 #define EN_BB 0x0008 68 #define EN_LO 0x0004 69 #define EN_BIAS 0x0001 70 71 #define EN_IQANA 0x0002 72 #define EN_DIGCLK 0x0080 /* not in the 0x24 reg, only in 0x1b */ 73 #define EN_CRYSTAL 0x0002 74 75 #define EN_UHF 0x22E9 76 #define EN_VHF 0x44E9 77 #define EN_LBD 0x11E9 78 #define EN_SBD 0x44E9 79 #define EN_CAB 0x88E9 80 81 /* Calibration defines */ 82 #define DC_CAL 0x1 83 #define WBD_CAL 0x2 84 #define TEMP_CAL 0x4 85 #define CAPTRIM_CAL 0x8 86 87 #define KROSUS_PLL_LOCKED 0x800 88 #define KROSUS 0x2 89 90 /* Use those defines to identify SOC version */ 91 #define SOC 0x02 92 #define SOC_7090_P1G_11R1 0x82 93 #define SOC_7090_P1G_21R1 0x8a 94 #define SOC_8090_P1G_11R1 0x86 95 #define SOC_8090_P1G_21R1 0x8e 96 97 /* else use thos ones to check */ 98 #define P1A_B 0x0 99 #define P1C 0x1 100 #define P1D_E_F 0x3 101 #define P1G 0x7 102 #define P1G_21R2 0xf 103 104 #define MP001 0x1 /* Single 9090/8096 */ 105 #define MP005 0x4 /* Single Sband */ 106 #define MP008 0x6 /* Dual diversity VHF-UHF-LBAND */ 107 #define MP009 0x7 /* Dual diversity 29098 CBAND-UHF-LBAND-SBAND */ 108 109 #define pgm_read_word(w) (*w) 110 111 struct dc_calibration; 112 113 struct dib0090_tuning { 114 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ 115 u8 switch_trim; 116 u8 lna_tune; 117 u16 lna_bias; 118 u16 v2i; 119 u16 mix; 120 u16 load; 121 u16 tuner_enable; 122 }; 123 124 struct dib0090_pll { 125 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ 126 u8 vco_band; 127 u8 hfdiv_code; 128 u8 hfdiv; 129 u8 topresc; 130 }; 131 132 struct dib0090_identity { 133 u8 version; 134 u8 product; 135 u8 p1g; 136 u8 in_soc; 137 }; 138 139 struct dib0090_state { 140 struct i2c_adapter *i2c; 141 struct dvb_frontend *fe; 142 const struct dib0090_config *config; 143 144 u8 current_band; 145 enum frontend_tune_state tune_state; 146 u32 current_rf; 147 148 u16 wbd_offset; 149 s16 wbd_target; /* in dB */ 150 151 s16 rf_gain_limit; /* take-over-point: where to split between bb and rf gain */ 152 s16 current_gain; /* keeps the currently programmed gain */ 153 u8 agc_step; /* new binary search */ 154 155 u16 gain[2]; /* for channel monitoring */ 156 157 const u16 *rf_ramp; 158 const u16 *bb_ramp; 159 160 /* for the software AGC ramps */ 161 u16 bb_1_def; 162 u16 rf_lt_def; 163 u16 gain_reg[4]; 164 165 /* for the captrim/dc-offset search */ 166 s8 step; 167 s16 adc_diff; 168 s16 min_adc_diff; 169 170 s8 captrim; 171 s8 fcaptrim; 172 173 const struct dc_calibration *dc; 174 u16 bb6, bb7; 175 176 const struct dib0090_tuning *current_tune_table_index; 177 const struct dib0090_pll *current_pll_table_index; 178 179 u8 tuner_is_tuned; 180 u8 agc_freeze; 181 182 struct dib0090_identity identity; 183 184 u32 rf_request; 185 u8 current_standard; 186 187 u8 calibrate; 188 u32 rest; 189 u16 bias; 190 s16 temperature; 191 192 u8 wbd_calibration_gain; 193 const struct dib0090_wbd_slope *current_wbd_table; 194 u16 wbdmux; 195 196 /* for the I2C transfer */ 197 struct i2c_msg msg[2]; 198 u8 i2c_write_buffer[3]; 199 u8 i2c_read_buffer[2]; 200 struct mutex i2c_buffer_lock; 201 }; 202 203 struct dib0090_fw_state { 204 struct i2c_adapter *i2c; 205 struct dvb_frontend *fe; 206 struct dib0090_identity identity; 207 const struct dib0090_config *config; 208 209 /* for the I2C transfer */ 210 struct i2c_msg msg; 211 u8 i2c_write_buffer[2]; 212 u8 i2c_read_buffer[2]; 213 struct mutex i2c_buffer_lock; 214 }; 215 216 static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) 217 { 218 u16 ret; 219 220 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { 221 dprintk("could not acquire lock\n"); 222 return 0; 223 } 224 225 state->i2c_write_buffer[0] = reg; 226 227 memset(state->msg, 0, 2 * sizeof(struct i2c_msg)); 228 state->msg[0].addr = state->config->i2c_address; 229 state->msg[0].flags = 0; 230 state->msg[0].buf = state->i2c_write_buffer; 231 state->msg[0].len = 1; 232 state->msg[1].addr = state->config->i2c_address; 233 state->msg[1].flags = I2C_M_RD; 234 state->msg[1].buf = state->i2c_read_buffer; 235 state->msg[1].len = 2; 236 237 if (i2c_transfer(state->i2c, state->msg, 2) != 2) { 238 pr_warn("DiB0090 I2C read failed\n"); 239 ret = 0; 240 } else 241 ret = (state->i2c_read_buffer[0] << 8) 242 | state->i2c_read_buffer[1]; 243 244 mutex_unlock(&state->i2c_buffer_lock); 245 return ret; 246 } 247 248 static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) 249 { 250 int ret; 251 252 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { 253 dprintk("could not acquire lock\n"); 254 return -EINVAL; 255 } 256 257 state->i2c_write_buffer[0] = reg & 0xff; 258 state->i2c_write_buffer[1] = val >> 8; 259 state->i2c_write_buffer[2] = val & 0xff; 260 261 memset(state->msg, 0, sizeof(struct i2c_msg)); 262 state->msg[0].addr = state->config->i2c_address; 263 state->msg[0].flags = 0; 264 state->msg[0].buf = state->i2c_write_buffer; 265 state->msg[0].len = 3; 266 267 if (i2c_transfer(state->i2c, state->msg, 1) != 1) { 268 pr_warn("DiB0090 I2C write failed\n"); 269 ret = -EREMOTEIO; 270 } else 271 ret = 0; 272 273 mutex_unlock(&state->i2c_buffer_lock); 274 return ret; 275 } 276 277 static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg) 278 { 279 u16 ret; 280 281 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { 282 dprintk("could not acquire lock\n"); 283 return 0; 284 } 285 286 state->i2c_write_buffer[0] = reg; 287 288 memset(&state->msg, 0, sizeof(struct i2c_msg)); 289 state->msg.addr = reg; 290 state->msg.flags = I2C_M_RD; 291 state->msg.buf = state->i2c_read_buffer; 292 state->msg.len = 2; 293 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) { 294 pr_warn("DiB0090 I2C read failed\n"); 295 ret = 0; 296 } else 297 ret = (state->i2c_read_buffer[0] << 8) 298 | state->i2c_read_buffer[1]; 299 300 mutex_unlock(&state->i2c_buffer_lock); 301 return ret; 302 } 303 304 static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val) 305 { 306 int ret; 307 308 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { 309 dprintk("could not acquire lock\n"); 310 return -EINVAL; 311 } 312 313 state->i2c_write_buffer[0] = val >> 8; 314 state->i2c_write_buffer[1] = val & 0xff; 315 316 memset(&state->msg, 0, sizeof(struct i2c_msg)); 317 state->msg.addr = reg; 318 state->msg.flags = 0; 319 state->msg.buf = state->i2c_write_buffer; 320 state->msg.len = 2; 321 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) { 322 pr_warn("DiB0090 I2C write failed\n"); 323 ret = -EREMOTEIO; 324 } else 325 ret = 0; 326 327 mutex_unlock(&state->i2c_buffer_lock); 328 return ret; 329 } 330 331 #define HARD_RESET(state) do { if (cfg->reset) { if (cfg->sleep) cfg->sleep(fe, 0); msleep(10); cfg->reset(fe, 1); msleep(10); cfg->reset(fe, 0); msleep(10); } } while (0) 332 #define ADC_TARGET -220 333 #define GAIN_ALPHA 5 334 #define WBD_ALPHA 6 335 #define LPF 100 336 static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c) 337 { 338 do { 339 dib0090_write_reg(state, r++, *b++); 340 } while (--c); 341 } 342 343 static int dib0090_identify(struct dvb_frontend *fe) 344 { 345 struct dib0090_state *state = fe->tuner_priv; 346 u16 v; 347 struct dib0090_identity *identity = &state->identity; 348 349 v = dib0090_read_reg(state, 0x1a); 350 351 identity->p1g = 0; 352 identity->in_soc = 0; 353 354 dprintk("Tuner identification (Version = 0x%04x)\n", v); 355 356 /* without PLL lock info */ 357 v &= ~KROSUS_PLL_LOCKED; 358 359 identity->version = v & 0xff; 360 identity->product = (v >> 8) & 0xf; 361 362 if (identity->product != KROSUS) 363 goto identification_error; 364 365 if ((identity->version & 0x3) == SOC) { 366 identity->in_soc = 1; 367 switch (identity->version) { 368 case SOC_8090_P1G_11R1: 369 dprintk("SOC 8090 P1-G11R1 Has been detected\n"); 370 identity->p1g = 1; 371 break; 372 case SOC_8090_P1G_21R1: 373 dprintk("SOC 8090 P1-G21R1 Has been detected\n"); 374 identity->p1g = 1; 375 break; 376 case SOC_7090_P1G_11R1: 377 dprintk("SOC 7090 P1-G11R1 Has been detected\n"); 378 identity->p1g = 1; 379 break; 380 case SOC_7090_P1G_21R1: 381 dprintk("SOC 7090 P1-G21R1 Has been detected\n"); 382 identity->p1g = 1; 383 break; 384 default: 385 goto identification_error; 386 } 387 } else { 388 switch ((identity->version >> 5) & 0x7) { 389 case MP001: 390 dprintk("MP001 : 9090/8096\n"); 391 break; 392 case MP005: 393 dprintk("MP005 : Single Sband\n"); 394 break; 395 case MP008: 396 dprintk("MP008 : diversity VHF-UHF-LBAND\n"); 397 break; 398 case MP009: 399 dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND\n"); 400 break; 401 default: 402 goto identification_error; 403 } 404 405 switch (identity->version & 0x1f) { 406 case P1G_21R2: 407 dprintk("P1G_21R2 detected\n"); 408 identity->p1g = 1; 409 break; 410 case P1G: 411 dprintk("P1G detected\n"); 412 identity->p1g = 1; 413 break; 414 case P1D_E_F: 415 dprintk("P1D/E/F detected\n"); 416 break; 417 case P1C: 418 dprintk("P1C detected\n"); 419 break; 420 case P1A_B: 421 dprintk("P1-A/B detected: driver is deactivated - not available\n"); 422 goto identification_error; 423 break; 424 default: 425 goto identification_error; 426 } 427 } 428 429 return 0; 430 431 identification_error: 432 return -EIO; 433 } 434 435 static int dib0090_fw_identify(struct dvb_frontend *fe) 436 { 437 struct dib0090_fw_state *state = fe->tuner_priv; 438 struct dib0090_identity *identity = &state->identity; 439 440 u16 v = dib0090_fw_read_reg(state, 0x1a); 441 identity->p1g = 0; 442 identity->in_soc = 0; 443 444 dprintk("FE: Tuner identification (Version = 0x%04x)\n", v); 445 446 /* without PLL lock info */ 447 v &= ~KROSUS_PLL_LOCKED; 448 449 identity->version = v & 0xff; 450 identity->product = (v >> 8) & 0xf; 451 452 if (identity->product != KROSUS) 453 goto identification_error; 454 455 if ((identity->version & 0x3) == SOC) { 456 identity->in_soc = 1; 457 switch (identity->version) { 458 case SOC_8090_P1G_11R1: 459 dprintk("SOC 8090 P1-G11R1 Has been detected\n"); 460 identity->p1g = 1; 461 break; 462 case SOC_8090_P1G_21R1: 463 dprintk("SOC 8090 P1-G21R1 Has been detected\n"); 464 identity->p1g = 1; 465 break; 466 case SOC_7090_P1G_11R1: 467 dprintk("SOC 7090 P1-G11R1 Has been detected\n"); 468 identity->p1g = 1; 469 break; 470 case SOC_7090_P1G_21R1: 471 dprintk("SOC 7090 P1-G21R1 Has been detected\n"); 472 identity->p1g = 1; 473 break; 474 default: 475 goto identification_error; 476 } 477 } else { 478 switch ((identity->version >> 5) & 0x7) { 479 case MP001: 480 dprintk("MP001 : 9090/8096\n"); 481 break; 482 case MP005: 483 dprintk("MP005 : Single Sband\n"); 484 break; 485 case MP008: 486 dprintk("MP008 : diversity VHF-UHF-LBAND\n"); 487 break; 488 case MP009: 489 dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND\n"); 490 break; 491 default: 492 goto identification_error; 493 } 494 495 switch (identity->version & 0x1f) { 496 case P1G_21R2: 497 dprintk("P1G_21R2 detected\n"); 498 identity->p1g = 1; 499 break; 500 case P1G: 501 dprintk("P1G detected\n"); 502 identity->p1g = 1; 503 break; 504 case P1D_E_F: 505 dprintk("P1D/E/F detected\n"); 506 break; 507 case P1C: 508 dprintk("P1C detected\n"); 509 break; 510 case P1A_B: 511 dprintk("P1-A/B detected: driver is deactivated - not available\n"); 512 goto identification_error; 513 break; 514 default: 515 goto identification_error; 516 } 517 } 518 519 return 0; 520 521 identification_error: 522 return -EIO; 523 } 524 525 static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg) 526 { 527 struct dib0090_state *state = fe->tuner_priv; 528 u16 PllCfg, i, v; 529 530 HARD_RESET(state); 531 dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL); 532 if (cfg->in_soc) 533 return; 534 535 dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */ 536 /* adcClkOutRatio=8->7, release reset */ 537 dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0); 538 if (cfg->clkoutdrive != 0) 539 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8) 540 | (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0)); 541 else 542 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8) 543 | (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0)); 544 545 /* Read Pll current config * */ 546 PllCfg = dib0090_read_reg(state, 0x21); 547 548 /** Reconfigure PLL if current setting is different from default setting **/ 549 if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && (!cfg->in_soc) 550 && !cfg->io.pll_bypass) { 551 552 /* Set Bypass mode */ 553 PllCfg |= (1 << 15); 554 dib0090_write_reg(state, 0x21, PllCfg); 555 556 /* Set Reset Pll */ 557 PllCfg &= ~(1 << 13); 558 dib0090_write_reg(state, 0x21, PllCfg); 559 560 /*** Set new Pll configuration in bypass and reset state ***/ 561 PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv); 562 dib0090_write_reg(state, 0x21, PllCfg); 563 564 /* Remove Reset Pll */ 565 PllCfg |= (1 << 13); 566 dib0090_write_reg(state, 0x21, PllCfg); 567 568 /*** Wait for PLL lock ***/ 569 i = 100; 570 do { 571 v = !!(dib0090_read_reg(state, 0x1a) & 0x800); 572 if (v) 573 break; 574 } while (--i); 575 576 if (i == 0) { 577 dprintk("Pll: Unable to lock Pll\n"); 578 return; 579 } 580 581 /* Finally Remove Bypass mode */ 582 PllCfg &= ~(1 << 15); 583 dib0090_write_reg(state, 0x21, PllCfg); 584 } 585 586 if (cfg->io.pll_bypass) { 587 PllCfg |= (cfg->io.pll_bypass << 15); 588 dib0090_write_reg(state, 0x21, PllCfg); 589 } 590 } 591 592 static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg) 593 { 594 struct dib0090_fw_state *state = fe->tuner_priv; 595 u16 PllCfg; 596 u16 v; 597 int i; 598 599 dprintk("fw reset digital\n"); 600 HARD_RESET(state); 601 602 dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL); 603 dib0090_fw_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */ 604 605 dib0090_fw_write_reg(state, 0x20, 606 ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (cfg->data_tx_drv << 4) | cfg->ls_cfg_pad_drv); 607 608 v = (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 9) | (0 << 8) | (cfg->clkouttobamse << 4) | (0 << 2) | (0); 609 if (cfg->clkoutdrive != 0) 610 v |= cfg->clkoutdrive << 5; 611 else 612 v |= 7 << 5; 613 614 v |= 2 << 10; 615 dib0090_fw_write_reg(state, 0x23, v); 616 617 /* Read Pll current config * */ 618 PllCfg = dib0090_fw_read_reg(state, 0x21); 619 620 /** Reconfigure PLL if current setting is different from default setting **/ 621 if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && !cfg->io.pll_bypass) { 622 623 /* Set Bypass mode */ 624 PllCfg |= (1 << 15); 625 dib0090_fw_write_reg(state, 0x21, PllCfg); 626 627 /* Set Reset Pll */ 628 PllCfg &= ~(1 << 13); 629 dib0090_fw_write_reg(state, 0x21, PllCfg); 630 631 /*** Set new Pll configuration in bypass and reset state ***/ 632 PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv); 633 dib0090_fw_write_reg(state, 0x21, PllCfg); 634 635 /* Remove Reset Pll */ 636 PllCfg |= (1 << 13); 637 dib0090_fw_write_reg(state, 0x21, PllCfg); 638 639 /*** Wait for PLL lock ***/ 640 i = 100; 641 do { 642 v = !!(dib0090_fw_read_reg(state, 0x1a) & 0x800); 643 if (v) 644 break; 645 } while (--i); 646 647 if (i == 0) { 648 dprintk("Pll: Unable to lock Pll\n"); 649 return -EIO; 650 } 651 652 /* Finally Remove Bypass mode */ 653 PllCfg &= ~(1 << 15); 654 dib0090_fw_write_reg(state, 0x21, PllCfg); 655 } 656 657 if (cfg->io.pll_bypass) { 658 PllCfg |= (cfg->io.pll_bypass << 15); 659 dib0090_fw_write_reg(state, 0x21, PllCfg); 660 } 661 662 return dib0090_fw_identify(fe); 663 } 664 665 static int dib0090_wakeup(struct dvb_frontend *fe) 666 { 667 struct dib0090_state *state = fe->tuner_priv; 668 if (state->config->sleep) 669 state->config->sleep(fe, 0); 670 671 /* enable dataTX in case we have been restarted in the wrong moment */ 672 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14)); 673 return 0; 674 } 675 676 static int dib0090_sleep(struct dvb_frontend *fe) 677 { 678 struct dib0090_state *state = fe->tuner_priv; 679 if (state->config->sleep) 680 state->config->sleep(fe, 1); 681 return 0; 682 } 683 684 void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast) 685 { 686 struct dib0090_state *state = fe->tuner_priv; 687 if (fast) 688 dib0090_write_reg(state, 0x04, 0); 689 else 690 dib0090_write_reg(state, 0x04, 1); 691 } 692 693 EXPORT_SYMBOL(dib0090_dcc_freq); 694 695 static const u16 bb_ramp_pwm_normal_socs[] = { 696 550, /* max BB gain in 10th of dB */ 697 (1<<9) | 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */ 698 440, 699 (4 << 9) | 0, /* BB_RAMP3 = 26dB */ 700 (0 << 9) | 208, /* BB_RAMP4 */ 701 (4 << 9) | 208, /* BB_RAMP5 = 29dB */ 702 (0 << 9) | 440, /* BB_RAMP6 */ 703 }; 704 705 static const u16 rf_ramp_pwm_cband_7090p[] = { 706 280, /* max RF gain in 10th of dB */ 707 18, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ 708 504, /* ramp_max = maximum X used on the ramp */ 709 (29 << 10) | 364, /* RF_RAMP5, LNA 1 = 8dB */ 710 (0 << 10) | 504, /* RF_RAMP6, LNA 1 */ 711 (60 << 10) | 228, /* RF_RAMP7, LNA 2 = 7.7dB */ 712 (0 << 10) | 364, /* RF_RAMP8, LNA 2 */ 713 (34 << 10) | 109, /* GAIN_4_1, LNA 3 = 6.8dB */ 714 (0 << 10) | 228, /* GAIN_4_2, LNA 3 */ 715 (37 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */ 716 (0 << 10) | 109, /* RF_RAMP4, LNA 4 */ 717 }; 718 719 static const u16 rf_ramp_pwm_cband_7090e_sensitivity[] = { 720 186, /* max RF gain in 10th of dB */ 721 40, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ 722 746, /* ramp_max = maximum X used on the ramp */ 723 (10 << 10) | 345, /* RF_RAMP5, LNA 1 = 10dB */ 724 (0 << 10) | 746, /* RF_RAMP6, LNA 1 */ 725 (0 << 10) | 0, /* RF_RAMP7, LNA 2 = 0 dB */ 726 (0 << 10) | 0, /* RF_RAMP8, LNA 2 */ 727 (28 << 10) | 200, /* GAIN_4_1, LNA 3 = 6.8dB */ /* 3.61 dB */ 728 (0 << 10) | 345, /* GAIN_4_2, LNA 3 */ 729 (20 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */ /* 4.96 dB */ 730 (0 << 10) | 200, /* RF_RAMP4, LNA 4 */ 731 }; 732 733 static const u16 rf_ramp_pwm_cband_7090e_aci[] = { 734 86, /* max RF gain in 10th of dB */ 735 40, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ 736 345, /* ramp_max = maximum X used on the ramp */ 737 (0 << 10) | 0, /* RF_RAMP5, LNA 1 = 8dB */ /* 7.47 dB */ 738 (0 << 10) | 0, /* RF_RAMP6, LNA 1 */ 739 (0 << 10) | 0, /* RF_RAMP7, LNA 2 = 0 dB */ 740 (0 << 10) | 0, /* RF_RAMP8, LNA 2 */ 741 (28 << 10) | 200, /* GAIN_4_1, LNA 3 = 6.8dB */ /* 3.61 dB */ 742 (0 << 10) | 345, /* GAIN_4_2, LNA 3 */ 743 (20 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */ /* 4.96 dB */ 744 (0 << 10) | 200, /* RF_RAMP4, LNA 4 */ 745 }; 746 747 static const u16 rf_ramp_pwm_cband_8090[] = { 748 345, /* max RF gain in 10th of dB */ 749 29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ 750 1000, /* ramp_max = maximum X used on the ramp */ 751 (35 << 10) | 772, /* RF_RAMP3, LNA 1 = 8dB */ 752 (0 << 10) | 1000, /* RF_RAMP4, LNA 1 */ 753 (58 << 10) | 496, /* RF_RAMP5, LNA 2 = 9.5dB */ 754 (0 << 10) | 772, /* RF_RAMP6, LNA 2 */ 755 (27 << 10) | 200, /* RF_RAMP7, LNA 3 = 10.5dB */ 756 (0 << 10) | 496, /* RF_RAMP8, LNA 3 */ 757 (40 << 10) | 0, /* GAIN_4_1, LNA 4 = 7dB */ 758 (0 << 10) | 200, /* GAIN_4_2, LNA 4 */ 759 }; 760 761 static const u16 rf_ramp_pwm_uhf_7090[] = { 762 407, /* max RF gain in 10th of dB */ 763 13, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ 764 529, /* ramp_max = maximum X used on the ramp */ 765 (23 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */ 766 (0 << 10) | 176, /* RF_RAMP4, LNA 1 */ 767 (63 << 10) | 400, /* RF_RAMP5, LNA 2 = 8dB */ 768 (0 << 10) | 529, /* RF_RAMP6, LNA 2 */ 769 (48 << 10) | 316, /* RF_RAMP7, LNA 3 = 6.8dB */ 770 (0 << 10) | 400, /* RF_RAMP8, LNA 3 */ 771 (29 << 10) | 176, /* GAIN_4_1, LNA 4 = 11.5dB */ 772 (0 << 10) | 316, /* GAIN_4_2, LNA 4 */ 773 }; 774 775 static const u16 rf_ramp_pwm_uhf_8090[] = { 776 388, /* max RF gain in 10th of dB */ 777 26, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ 778 1008, /* ramp_max = maximum X used on the ramp */ 779 (11 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */ 780 (0 << 10) | 369, /* RF_RAMP4, LNA 1 */ 781 (41 << 10) | 809, /* RF_RAMP5, LNA 2 = 8dB */ 782 (0 << 10) | 1008, /* RF_RAMP6, LNA 2 */ 783 (27 << 10) | 659, /* RF_RAMP7, LNA 3 = 6dB */ 784 (0 << 10) | 809, /* RF_RAMP8, LNA 3 */ 785 (14 << 10) | 369, /* GAIN_4_1, LNA 4 = 11.5dB */ 786 (0 << 10) | 659, /* GAIN_4_2, LNA 4 */ 787 }; 788 789 /* GENERAL PWM ramp definition for all other Krosus */ 790 static const u16 bb_ramp_pwm_normal[] = { 791 500, /* max BB gain in 10th of dB */ 792 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */ 793 400, 794 (2 << 9) | 0, /* BB_RAMP3 = 21dB */ 795 (0 << 9) | 168, /* BB_RAMP4 */ 796 (2 << 9) | 168, /* BB_RAMP5 = 29dB */ 797 (0 << 9) | 400, /* BB_RAMP6 */ 798 }; 799 800 #if 0 801 /* Currently unused */ 802 static const u16 bb_ramp_pwm_boost[] = { 803 550, /* max BB gain in 10th of dB */ 804 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */ 805 440, 806 (2 << 9) | 0, /* BB_RAMP3 = 26dB */ 807 (0 << 9) | 208, /* BB_RAMP4 */ 808 (2 << 9) | 208, /* BB_RAMP5 = 29dB */ 809 (0 << 9) | 440, /* BB_RAMP6 */ 810 }; 811 #endif 812 813 static const u16 rf_ramp_pwm_cband[] = { 814 314, /* max RF gain in 10th of dB */ 815 33, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ 816 1023, /* ramp_max = maximum X used on the ramp */ 817 (8 << 10) | 743, /* RF_RAMP3, LNA 1 = 0dB */ 818 (0 << 10) | 1023, /* RF_RAMP4, LNA 1 */ 819 (15 << 10) | 469, /* RF_RAMP5, LNA 2 = 0dB */ 820 (0 << 10) | 742, /* RF_RAMP6, LNA 2 */ 821 (9 << 10) | 234, /* RF_RAMP7, LNA 3 = 0dB */ 822 (0 << 10) | 468, /* RF_RAMP8, LNA 3 */ 823 (9 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */ 824 (0 << 10) | 233, /* GAIN_4_2, LNA 4 */ 825 }; 826 827 static const u16 rf_ramp_pwm_vhf[] = { 828 398, /* max RF gain in 10th of dB */ 829 24, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ 830 954, /* ramp_max = maximum X used on the ramp */ 831 (7 << 10) | 0, /* RF_RAMP3, LNA 1 = 13.2dB */ 832 (0 << 10) | 290, /* RF_RAMP4, LNA 1 */ 833 (16 << 10) | 699, /* RF_RAMP5, LNA 2 = 10.5dB */ 834 (0 << 10) | 954, /* RF_RAMP6, LNA 2 */ 835 (17 << 10) | 580, /* RF_RAMP7, LNA 3 = 5dB */ 836 (0 << 10) | 699, /* RF_RAMP8, LNA 3 */ 837 (7 << 10) | 290, /* GAIN_4_1, LNA 4 = 12.5dB */ 838 (0 << 10) | 580, /* GAIN_4_2, LNA 4 */ 839 }; 840 841 static const u16 rf_ramp_pwm_uhf[] = { 842 398, /* max RF gain in 10th of dB */ 843 24, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ 844 954, /* ramp_max = maximum X used on the ramp */ 845 (7 << 10) | 0, /* RF_RAMP3, LNA 1 = 13.2dB */ 846 (0 << 10) | 290, /* RF_RAMP4, LNA 1 */ 847 (16 << 10) | 699, /* RF_RAMP5, LNA 2 = 10.5dB */ 848 (0 << 10) | 954, /* RF_RAMP6, LNA 2 */ 849 (17 << 10) | 580, /* RF_RAMP7, LNA 3 = 5dB */ 850 (0 << 10) | 699, /* RF_RAMP8, LNA 3 */ 851 (7 << 10) | 290, /* GAIN_4_1, LNA 4 = 12.5dB */ 852 (0 << 10) | 580, /* GAIN_4_2, LNA 4 */ 853 }; 854 855 #if 0 856 /* Currently unused */ 857 static const u16 rf_ramp_pwm_sband[] = { 858 253, /* max RF gain in 10th of dB */ 859 38, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ 860 961, 861 (4 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.1dB */ 862 (0 << 10) | 508, /* RF_RAMP4, LNA 1 */ 863 (9 << 10) | 508, /* RF_RAMP5, LNA 2 = 11.2dB */ 864 (0 << 10) | 961, /* RF_RAMP6, LNA 2 */ 865 (0 << 10) | 0, /* RF_RAMP7, LNA 3 = 0dB */ 866 (0 << 10) | 0, /* RF_RAMP8, LNA 3 */ 867 (0 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */ 868 (0 << 10) | 0, /* GAIN_4_2, LNA 4 */ 869 }; 870 #endif 871 872 struct slope { 873 s16 range; 874 s16 slope; 875 }; 876 static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val) 877 { 878 u8 i; 879 u16 rest; 880 u16 ret = 0; 881 for (i = 0; i < num; i++) { 882 if (val > slopes[i].range) 883 rest = slopes[i].range; 884 else 885 rest = val; 886 ret += (rest * slopes[i].slope) / slopes[i].range; 887 val -= rest; 888 } 889 return ret; 890 } 891 892 static const struct slope dib0090_wbd_slopes[3] = { 893 {66, 120}, /* -64,-52: offset - 65 */ 894 {600, 170}, /* -52,-35: 65 - 665 */ 895 {170, 250}, /* -45,-10: 665 - 835 */ 896 }; 897 898 static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd) 899 { 900 wbd &= 0x3ff; 901 if (wbd < state->wbd_offset) 902 wbd = 0; 903 else 904 wbd -= state->wbd_offset; 905 /* -64dB is the floor */ 906 return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd); 907 } 908 909 static void dib0090_wbd_target(struct dib0090_state *state, u32 rf) 910 { 911 u16 offset = 250; 912 913 /* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */ 914 915 if (state->current_band == BAND_VHF) 916 offset = 650; 917 #ifndef FIRMWARE_FIREFLY 918 if (state->current_band == BAND_VHF) 919 offset = state->config->wbd_vhf_offset; 920 if (state->current_band == BAND_CBAND) 921 offset = state->config->wbd_cband_offset; 922 #endif 923 924 state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset); 925 dprintk("wbd-target: %d dB\n", (u32) state->wbd_target); 926 } 927 928 static const int gain_reg_addr[4] = { 929 0x08, 0x0a, 0x0f, 0x01 930 }; 931 932 static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force) 933 { 934 u16 rf, bb, ref; 935 u16 i, v, gain_reg[4] = { 0 }, gain; 936 const u16 *g; 937 938 if (top_delta < -511) 939 top_delta = -511; 940 if (top_delta > 511) 941 top_delta = 511; 942 943 if (force) { 944 top_delta *= (1 << WBD_ALPHA); 945 gain_delta *= (1 << GAIN_ALPHA); 946 } 947 948 if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit)) /* overflow */ 949 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA; 950 else 951 state->rf_gain_limit += top_delta; 952 953 if (state->rf_gain_limit < 0) /*underflow */ 954 state->rf_gain_limit = 0; 955 956 /* use gain as a temporary variable and correct current_gain */ 957 gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA; 958 if (gain_delta >= ((s16) gain - state->current_gain)) /* overflow */ 959 state->current_gain = gain; 960 else 961 state->current_gain += gain_delta; 962 /* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */ 963 if (state->current_gain < 0) 964 state->current_gain = 0; 965 966 /* now split total gain to rf and bb gain */ 967 gain = state->current_gain >> GAIN_ALPHA; 968 969 /* requested gain is bigger than rf gain limit - ACI/WBD adjustment */ 970 if (gain > (state->rf_gain_limit >> WBD_ALPHA)) { 971 rf = state->rf_gain_limit >> WBD_ALPHA; 972 bb = gain - rf; 973 if (bb > state->bb_ramp[0]) 974 bb = state->bb_ramp[0]; 975 } else { /* high signal level -> all gains put on RF */ 976 rf = gain; 977 bb = 0; 978 } 979 980 state->gain[0] = rf; 981 state->gain[1] = bb; 982 983 /* software ramp */ 984 /* Start with RF gains */ 985 g = state->rf_ramp + 1; /* point on RF LNA1 max gain */ 986 ref = rf; 987 for (i = 0; i < 7; i++) { /* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */ 988 if (g[0] == 0 || ref < (g[1] - g[0])) /* if total gain of the current amp is null or this amp is not concerned because it starts to work from an higher gain value */ 989 v = 0; /* force the gain to write for the current amp to be null */ 990 else if (ref >= g[1]) /* Gain to set is higher than the high working point of this amp */ 991 v = g[2]; /* force this amp to be full gain */ 992 else /* compute the value to set to this amp because we are somewhere in his range */ 993 v = ((ref - (g[1] - g[0])) * g[2]) / g[0]; 994 995 if (i == 0) /* LNA 1 reg mapping */ 996 gain_reg[0] = v; 997 else if (i == 1) /* LNA 2 reg mapping */ 998 gain_reg[0] |= v << 7; 999 else if (i == 2) /* LNA 3 reg mapping */ 1000 gain_reg[1] = v; 1001 else if (i == 3) /* LNA 4 reg mapping */ 1002 gain_reg[1] |= v << 7; 1003 else if (i == 4) /* CBAND LNA reg mapping */ 1004 gain_reg[2] = v | state->rf_lt_def; 1005 else if (i == 5) /* BB gain 1 reg mapping */ 1006 gain_reg[3] = v << 3; 1007 else if (i == 6) /* BB gain 2 reg mapping */ 1008 gain_reg[3] |= v << 8; 1009 1010 g += 3; /* go to next gain bloc */ 1011 1012 /* When RF is finished, start with BB */ 1013 if (i == 4) { 1014 g = state->bb_ramp + 1; /* point on BB gain 1 max gain */ 1015 ref = bb; 1016 } 1017 } 1018 gain_reg[3] |= state->bb_1_def; 1019 gain_reg[3] |= ((bb % 10) * 100) / 125; 1020 1021 #ifdef DEBUG_AGC 1022 dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x\n", rf, bb, rf + bb, 1023 gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]); 1024 #endif 1025 1026 /* Write the amplifier regs */ 1027 for (i = 0; i < 4; i++) { 1028 v = gain_reg[i]; 1029 if (force || state->gain_reg[i] != v) { 1030 state->gain_reg[i] = v; 1031 dib0090_write_reg(state, gain_reg_addr[i], v); 1032 } 1033 } 1034 } 1035 1036 static void dib0090_set_boost(struct dib0090_state *state, int onoff) 1037 { 1038 state->bb_1_def &= 0xdfff; 1039 state->bb_1_def |= onoff << 13; 1040 } 1041 1042 static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg) 1043 { 1044 state->rf_ramp = cfg; 1045 } 1046 1047 static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg) 1048 { 1049 state->rf_ramp = cfg; 1050 1051 dib0090_write_reg(state, 0x2a, 0xffff); 1052 1053 dprintk("total RF gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x2a)); 1054 1055 dib0090_write_regs(state, 0x2c, cfg + 3, 6); 1056 dib0090_write_regs(state, 0x3e, cfg + 9, 2); 1057 } 1058 1059 static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg) 1060 { 1061 state->bb_ramp = cfg; 1062 dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */ 1063 } 1064 1065 static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg) 1066 { 1067 state->bb_ramp = cfg; 1068 1069 dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */ 1070 1071 dib0090_write_reg(state, 0x33, 0xffff); 1072 dprintk("total BB gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x33)); 1073 dib0090_write_regs(state, 0x35, cfg + 3, 4); 1074 } 1075 1076 void dib0090_pwm_gain_reset(struct dvb_frontend *fe) 1077 { 1078 struct dib0090_state *state = fe->tuner_priv; 1079 u16 *bb_ramp = (u16 *)&bb_ramp_pwm_normal; /* default baseband config */ 1080 u16 *rf_ramp = NULL; 1081 u8 en_pwm_rf_mux = 1; 1082 1083 /* reset the AGC */ 1084 if (state->config->use_pwm_agc) { 1085 if (state->current_band == BAND_CBAND) { 1086 if (state->identity.in_soc) { 1087 bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs; 1088 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1) 1089 rf_ramp = (u16 *)&rf_ramp_pwm_cband_8090; 1090 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) { 1091 if (state->config->is_dib7090e) { 1092 if (state->rf_ramp == NULL) 1093 rf_ramp = (u16 *)&rf_ramp_pwm_cband_7090e_sensitivity; 1094 else 1095 rf_ramp = (u16 *)state->rf_ramp; 1096 } else 1097 rf_ramp = (u16 *)&rf_ramp_pwm_cband_7090p; 1098 } 1099 } else 1100 rf_ramp = (u16 *)&rf_ramp_pwm_cband; 1101 } else 1102 1103 if (state->current_band == BAND_VHF) { 1104 if (state->identity.in_soc) { 1105 bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs; 1106 /* rf_ramp = &rf_ramp_pwm_vhf_socs; */ /* TODO */ 1107 } else 1108 rf_ramp = (u16 *)&rf_ramp_pwm_vhf; 1109 } else if (state->current_band == BAND_UHF) { 1110 if (state->identity.in_soc) { 1111 bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs; 1112 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1) 1113 rf_ramp = (u16 *)&rf_ramp_pwm_uhf_8090; 1114 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) 1115 rf_ramp = (u16 *)&rf_ramp_pwm_uhf_7090; 1116 } else 1117 rf_ramp = (u16 *)&rf_ramp_pwm_uhf; 1118 } 1119 if (rf_ramp) 1120 dib0090_set_rframp_pwm(state, rf_ramp); 1121 dib0090_set_bbramp_pwm(state, bb_ramp); 1122 1123 /* activate the ramp generator using PWM control */ 1124 if (state->rf_ramp) 1125 dprintk("ramp RF gain = %d BAND = %s version = %d\n", 1126 state->rf_ramp[0], 1127 (state->current_band == BAND_CBAND) ? "CBAND" : "NOT CBAND", 1128 state->identity.version & 0x1f); 1129 1130 if (rf_ramp && ((state->rf_ramp && state->rf_ramp[0] == 0) || 1131 (state->current_band == BAND_CBAND && 1132 (state->identity.version & 0x1f) <= P1D_E_F))) { 1133 dprintk("DE-Engage mux for direct gain reg control\n"); 1134 en_pwm_rf_mux = 0; 1135 } else 1136 dprintk("Engage mux for PWM control\n"); 1137 1138 dib0090_write_reg(state, 0x32, (en_pwm_rf_mux << 12) | (en_pwm_rf_mux << 11)); 1139 1140 /* Set fast servo cutoff to start AGC; 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast*/ 1141 if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) 1142 dib0090_write_reg(state, 0x04, 3); 1143 else 1144 dib0090_write_reg(state, 0x04, 1); 1145 dib0090_write_reg(state, 0x39, (1 << 10)); /* 0 gain by default */ 1146 } 1147 } 1148 EXPORT_SYMBOL(dib0090_pwm_gain_reset); 1149 1150 void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff) 1151 { 1152 struct dib0090_state *state = fe->tuner_priv; 1153 if (DC_servo_cutoff < 4) 1154 dib0090_write_reg(state, 0x04, DC_servo_cutoff); 1155 } 1156 EXPORT_SYMBOL(dib0090_set_dc_servo); 1157 1158 static u32 dib0090_get_slow_adc_val(struct dib0090_state *state) 1159 { 1160 u16 adc_val = dib0090_read_reg(state, 0x1d); 1161 if (state->identity.in_soc) 1162 adc_val >>= 2; 1163 return adc_val; 1164 } 1165 1166 int dib0090_gain_control(struct dvb_frontend *fe) 1167 { 1168 struct dib0090_state *state = fe->tuner_priv; 1169 enum frontend_tune_state *tune_state = &state->tune_state; 1170 int ret = 10; 1171 1172 u16 wbd_val = 0; 1173 u8 apply_gain_immediatly = 1; 1174 s16 wbd_error = 0, adc_error = 0; 1175 1176 if (*tune_state == CT_AGC_START) { 1177 state->agc_freeze = 0; 1178 dib0090_write_reg(state, 0x04, 0x0); 1179 1180 #ifdef CONFIG_BAND_SBAND 1181 if (state->current_band == BAND_SBAND) { 1182 dib0090_set_rframp(state, rf_ramp_sband); 1183 dib0090_set_bbramp(state, bb_ramp_boost); 1184 } else 1185 #endif 1186 #ifdef CONFIG_BAND_VHF 1187 if (state->current_band == BAND_VHF && !state->identity.p1g) { 1188 dib0090_set_rframp(state, rf_ramp_pwm_vhf); 1189 dib0090_set_bbramp(state, bb_ramp_pwm_normal); 1190 } else 1191 #endif 1192 #ifdef CONFIG_BAND_CBAND 1193 if (state->current_band == BAND_CBAND && !state->identity.p1g) { 1194 dib0090_set_rframp(state, rf_ramp_pwm_cband); 1195 dib0090_set_bbramp(state, bb_ramp_pwm_normal); 1196 } else 1197 #endif 1198 if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) { 1199 dib0090_set_rframp(state, rf_ramp_pwm_cband_7090p); 1200 dib0090_set_bbramp(state, bb_ramp_pwm_normal_socs); 1201 } else { 1202 dib0090_set_rframp(state, rf_ramp_pwm_uhf); 1203 dib0090_set_bbramp(state, bb_ramp_pwm_normal); 1204 } 1205 1206 dib0090_write_reg(state, 0x32, 0); 1207 dib0090_write_reg(state, 0x39, 0); 1208 1209 dib0090_wbd_target(state, state->current_rf); 1210 1211 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA; 1212 state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA; 1213 1214 *tune_state = CT_AGC_STEP_0; 1215 } else if (!state->agc_freeze) { 1216 s16 wbd = 0, i, cnt; 1217 1218 int adc; 1219 wbd_val = dib0090_get_slow_adc_val(state); 1220 1221 if (*tune_state == CT_AGC_STEP_0) 1222 cnt = 5; 1223 else 1224 cnt = 1; 1225 1226 for (i = 0; i < cnt; i++) { 1227 wbd_val = dib0090_get_slow_adc_val(state); 1228 wbd += dib0090_wbd_to_db(state, wbd_val); 1229 } 1230 wbd /= cnt; 1231 wbd_error = state->wbd_target - wbd; 1232 1233 if (*tune_state == CT_AGC_STEP_0) { 1234 if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) { 1235 #ifdef CONFIG_BAND_CBAND 1236 /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */ 1237 u8 ltg2 = (state->rf_lt_def >> 10) & 0x7; 1238 if (state->current_band == BAND_CBAND && ltg2) { 1239 ltg2 >>= 1; 1240 state->rf_lt_def &= ltg2 << 10; /* reduce in 3 steps from 7 to 0 */ 1241 } 1242 #endif 1243 } else { 1244 state->agc_step = 0; 1245 *tune_state = CT_AGC_STEP_1; 1246 } 1247 } else { 1248 /* calc the adc power */ 1249 adc = state->config->get_adc_power(fe); 1250 adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21; /* included in [0:-700] */ 1251 1252 adc_error = (s16) (((s32) ADC_TARGET) - adc); 1253 #ifdef CONFIG_STANDARD_DAB 1254 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) 1255 adc_error -= 10; 1256 #endif 1257 #ifdef CONFIG_STANDARD_DVBT 1258 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT && 1259 (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16)) 1260 adc_error += 60; 1261 #endif 1262 #ifdef CONFIG_SYS_ISDBT 1263 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count > 1264 0) 1265 && 1266 ((state->fe->dtv_property_cache.layer[0].modulation == 1267 QAM_64) 1268 || (state->fe->dtv_property_cache. 1269 layer[0].modulation == QAM_16))) 1270 || 1271 ((state->fe->dtv_property_cache.layer[1].segment_count > 1272 0) 1273 && 1274 ((state->fe->dtv_property_cache.layer[1].modulation == 1275 QAM_64) 1276 || (state->fe->dtv_property_cache. 1277 layer[1].modulation == QAM_16))) 1278 || 1279 ((state->fe->dtv_property_cache.layer[2].segment_count > 1280 0) 1281 && 1282 ((state->fe->dtv_property_cache.layer[2].modulation == 1283 QAM_64) 1284 || (state->fe->dtv_property_cache. 1285 layer[2].modulation == QAM_16))) 1286 ) 1287 ) 1288 adc_error += 60; 1289 #endif 1290 1291 if (*tune_state == CT_AGC_STEP_1) { /* quickly go to the correct range of the ADC power */ 1292 if (ABS(adc_error) < 50 || state->agc_step++ > 5) { 1293 1294 #ifdef CONFIG_STANDARD_DAB 1295 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) { 1296 dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63)); /* cap value = 63 : narrow BB filter : Fc = 1.8MHz */ 1297 dib0090_write_reg(state, 0x04, 0x0); 1298 } else 1299 #endif 1300 { 1301 dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32)); 1302 dib0090_write_reg(state, 0x04, 0x01); /*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */ 1303 } 1304 1305 *tune_state = CT_AGC_STOP; 1306 } 1307 } else { 1308 /* everything higher than or equal to CT_AGC_STOP means tracking */ 1309 ret = 100; /* 10ms interval */ 1310 apply_gain_immediatly = 0; 1311 } 1312 } 1313 #ifdef DEBUG_AGC 1314 dprintk 1315 ("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm", 1316 (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val, 1317 (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA)); 1318 #endif 1319 } 1320 1321 /* apply gain */ 1322 if (!state->agc_freeze) 1323 dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly); 1324 return ret; 1325 } 1326 1327 EXPORT_SYMBOL(dib0090_gain_control); 1328 1329 void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt) 1330 { 1331 struct dib0090_state *state = fe->tuner_priv; 1332 if (rf) 1333 *rf = state->gain[0]; 1334 if (bb) 1335 *bb = state->gain[1]; 1336 if (rf_gain_limit) 1337 *rf_gain_limit = state->rf_gain_limit; 1338 if (rflt) 1339 *rflt = (state->rf_lt_def >> 10) & 0x7; 1340 } 1341 1342 EXPORT_SYMBOL(dib0090_get_current_gain); 1343 1344 u16 dib0090_get_wbd_target(struct dvb_frontend *fe) 1345 { 1346 struct dib0090_state *state = fe->tuner_priv; 1347 u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000; 1348 s32 current_temp = state->temperature; 1349 s32 wbd_thot, wbd_tcold; 1350 const struct dib0090_wbd_slope *wbd = state->current_wbd_table; 1351 1352 while (f_MHz > wbd->max_freq) 1353 wbd++; 1354 1355 dprintk("using wbd-table-entry with max freq %d\n", wbd->max_freq); 1356 1357 if (current_temp < 0) 1358 current_temp = 0; 1359 if (current_temp > 128) 1360 current_temp = 128; 1361 1362 state->wbdmux &= ~(7 << 13); 1363 if (wbd->wbd_gain != 0) 1364 state->wbdmux |= (wbd->wbd_gain << 13); 1365 else 1366 state->wbdmux |= (4 << 13); 1367 1368 dib0090_write_reg(state, 0x10, state->wbdmux); 1369 1370 wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6); 1371 wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6); 1372 1373 wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7; 1374 1375 state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold); 1376 dprintk("wbd-target: %d dB\n", (u32) state->wbd_target); 1377 dprintk("wbd offset applied is %d\n", wbd_tcold); 1378 1379 return state->wbd_offset + wbd_tcold; 1380 } 1381 EXPORT_SYMBOL(dib0090_get_wbd_target); 1382 1383 u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) 1384 { 1385 struct dib0090_state *state = fe->tuner_priv; 1386 return state->wbd_offset; 1387 } 1388 EXPORT_SYMBOL(dib0090_get_wbd_offset); 1389 1390 int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3) 1391 { 1392 struct dib0090_state *state = fe->tuner_priv; 1393 1394 dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8) 1395 | ((sw3 & 1) << 2) | ((sw2 & 1) << 1) | (sw1 & 1)); 1396 1397 return 0; 1398 } 1399 EXPORT_SYMBOL(dib0090_set_switch); 1400 1401 int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff) 1402 { 1403 struct dib0090_state *state = fe->tuner_priv; 1404 1405 dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff) 1406 | ((onoff & 1) << 15)); 1407 return 0; 1408 } 1409 EXPORT_SYMBOL(dib0090_set_vga); 1410 1411 int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity) 1412 { 1413 struct dib0090_state *state = fe->tuner_priv; 1414 1415 if ((!state->identity.p1g) || (!state->identity.in_soc) 1416 || ((state->identity.version != SOC_7090_P1G_21R1) 1417 && (state->identity.version != SOC_7090_P1G_11R1))) { 1418 dprintk("%s() function can only be used for dib7090P\n", __func__); 1419 return -ENODEV; 1420 } 1421 1422 if (cfg_sensitivity) 1423 state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_sensitivity; 1424 else 1425 state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_aci; 1426 dib0090_pwm_gain_reset(fe); 1427 1428 return 0; 1429 } 1430 EXPORT_SYMBOL(dib0090_update_rframp_7090); 1431 1432 static const u16 dib0090_defaults[] = { 1433 1434 25, 0x01, 1435 0x0000, 1436 0x99a0, 1437 0x6008, 1438 0x0000, 1439 0x8bcb, 1440 0x0000, 1441 0x0405, 1442 0x0000, 1443 0x0000, 1444 0x0000, 1445 0xb802, 1446 0x0300, 1447 0x2d12, 1448 0xbac0, 1449 0x7c00, 1450 0xdbb9, 1451 0x0954, 1452 0x0743, 1453 0x8000, 1454 0x0001, 1455 0x0040, 1456 0x0100, 1457 0x0000, 1458 0xe910, 1459 0x149e, 1460 1461 1, 0x1c, 1462 0xff2d, 1463 1464 1, 0x39, 1465 0x0000, 1466 1467 2, 0x1e, 1468 0x07FF, 1469 0x0007, 1470 1471 1, 0x24, 1472 EN_UHF | EN_CRYSTAL, 1473 1474 2, 0x3c, 1475 0x3ff, 1476 0x111, 1477 0 1478 }; 1479 1480 static const u16 dib0090_p1g_additionnal_defaults[] = { 1481 1, 0x05, 1482 0xabcd, 1483 1484 1, 0x11, 1485 0x00b4, 1486 1487 1, 0x1c, 1488 0xfffd, 1489 1490 1, 0x40, 1491 0x108, 1492 0 1493 }; 1494 1495 static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n) 1496 { 1497 u16 l, r; 1498 1499 l = pgm_read_word(n++); 1500 while (l) { 1501 r = pgm_read_word(n++); 1502 do { 1503 dib0090_write_reg(state, r, pgm_read_word(n++)); 1504 r++; 1505 } while (--l); 1506 l = pgm_read_word(n++); 1507 } 1508 } 1509 1510 #define CAP_VALUE_MIN (u8) 9 1511 #define CAP_VALUE_MAX (u8) 40 1512 #define HR_MIN (u8) 25 1513 #define HR_MAX (u8) 40 1514 #define POLY_MIN (u8) 0 1515 #define POLY_MAX (u8) 8 1516 1517 static void dib0090_set_EFUSE(struct dib0090_state *state) 1518 { 1519 u8 c, h, n; 1520 u16 e2, e4; 1521 u16 cal; 1522 1523 e2 = dib0090_read_reg(state, 0x26); 1524 e4 = dib0090_read_reg(state, 0x28); 1525 1526 if ((state->identity.version == P1D_E_F) || 1527 (state->identity.version == P1G) || (e2 == 0xffff)) { 1528 1529 dib0090_write_reg(state, 0x22, 0x10); 1530 cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff; 1531 1532 if ((cal < 670) || (cal == 1023)) 1533 cal = 850; 1534 n = 165 - ((cal * 10)>>6) ; 1535 e2 = e4 = (3<<12) | (34<<6) | (n); 1536 } 1537 1538 if (e2 != e4) 1539 e2 &= e4; /* Remove the redundancy */ 1540 1541 if (e2 != 0xffff) { 1542 c = e2 & 0x3f; 1543 n = (e2 >> 12) & 0xf; 1544 h = (e2 >> 6) & 0x3f; 1545 1546 if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN)) 1547 c = 32; 1548 else 1549 c += 14; 1550 if ((h >= HR_MAX) || (h <= HR_MIN)) 1551 h = 34; 1552 if ((n >= POLY_MAX) || (n <= POLY_MIN)) 1553 n = 3; 1554 1555 dib0090_write_reg(state, 0x13, (h << 10)); 1556 e2 = (n << 11) | ((h >> 2)<<6) | c; 1557 dib0090_write_reg(state, 0x2, e2); /* Load the BB_2 */ 1558 } 1559 } 1560 1561 static int dib0090_reset(struct dvb_frontend *fe) 1562 { 1563 struct dib0090_state *state = fe->tuner_priv; 1564 1565 dib0090_reset_digital(fe, state->config); 1566 if (dib0090_identify(fe) < 0) 1567 return -EIO; 1568 1569 #ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT 1570 if (!(state->identity.version & 0x1)) /* it is P1B - reset is already done */ 1571 return 0; 1572 #endif 1573 1574 if (!state->identity.in_soc) { 1575 if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2) 1576 dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL)); 1577 else 1578 dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL)); 1579 } 1580 1581 dib0090_set_default_config(state, dib0090_defaults); 1582 1583 if (state->identity.in_soc) 1584 dib0090_write_reg(state, 0x18, 0x2910); /* charge pump current = 0 */ 1585 1586 if (state->identity.p1g) 1587 dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults); 1588 1589 /* Update the efuse : Only available for KROSUS > P1C and SOC as well*/ 1590 if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc)) 1591 dib0090_set_EFUSE(state); 1592 1593 /* Congigure in function of the crystal */ 1594 if (state->config->force_crystal_mode != 0) 1595 dib0090_write_reg(state, 0x14, 1596 state->config->force_crystal_mode & 3); 1597 else if (state->config->io.clock_khz >= 24000) 1598 dib0090_write_reg(state, 0x14, 1); 1599 else 1600 dib0090_write_reg(state, 0x14, 2); 1601 dprintk("Pll lock : %d\n", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1); 1602 1603 state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL; /* enable iq-offset-calibration and wbd-calibration when tuning next time */ 1604 1605 return 0; 1606 } 1607 1608 #define steps(u) (((u) > 15) ? ((u)-16) : (u)) 1609 #define INTERN_WAIT 10 1610 static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state) 1611 { 1612 int ret = INTERN_WAIT * 10; 1613 1614 switch (*tune_state) { 1615 case CT_TUNER_STEP_2: 1616 /* Turns to positive */ 1617 dib0090_write_reg(state, 0x1f, 0x7); 1618 *tune_state = CT_TUNER_STEP_3; 1619 break; 1620 1621 case CT_TUNER_STEP_3: 1622 state->adc_diff = dib0090_read_reg(state, 0x1d); 1623 1624 /* Turns to negative */ 1625 dib0090_write_reg(state, 0x1f, 0x4); 1626 *tune_state = CT_TUNER_STEP_4; 1627 break; 1628 1629 case CT_TUNER_STEP_4: 1630 state->adc_diff -= dib0090_read_reg(state, 0x1d); 1631 *tune_state = CT_TUNER_STEP_5; 1632 ret = 0; 1633 break; 1634 1635 default: 1636 break; 1637 } 1638 1639 return ret; 1640 } 1641 1642 struct dc_calibration { 1643 u8 addr; 1644 u8 offset; 1645 u8 pga:1; 1646 u16 bb1; 1647 u8 i:1; 1648 }; 1649 1650 static const struct dc_calibration dc_table[] = { 1651 /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */ 1652 {0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1}, 1653 {0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0}, 1654 /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */ 1655 {0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1}, 1656 {0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0}, 1657 {0}, 1658 }; 1659 1660 static const struct dc_calibration dc_p1g_table[] = { 1661 /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */ 1662 /* addr ; trim reg offset ; pga ; CTRL_BB1 value ; i or q */ 1663 {0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1}, 1664 {0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0}, 1665 /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */ 1666 {0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1}, 1667 {0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0}, 1668 {0}, 1669 }; 1670 1671 static void dib0090_set_trim(struct dib0090_state *state) 1672 { 1673 u16 *val; 1674 1675 if (state->dc->addr == 0x07) 1676 val = &state->bb7; 1677 else 1678 val = &state->bb6; 1679 1680 *val &= ~(0x1f << state->dc->offset); 1681 *val |= state->step << state->dc->offset; 1682 1683 dib0090_write_reg(state, state->dc->addr, *val); 1684 } 1685 1686 static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state) 1687 { 1688 int ret = 0; 1689 u16 reg; 1690 1691 switch (*tune_state) { 1692 case CT_TUNER_START: 1693 dprintk("Start DC offset calibration"); 1694 1695 /* force vcm2 = 0.8V */ 1696 state->bb6 = 0; 1697 state->bb7 = 0x040d; 1698 1699 /* the LNA AND LO are off */ 1700 reg = dib0090_read_reg(state, 0x24) & 0x0ffb; /* shutdown lna and lo */ 1701 dib0090_write_reg(state, 0x24, reg); 1702 1703 state->wbdmux = dib0090_read_reg(state, 0x10); 1704 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3); 1705 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14)); 1706 1707 state->dc = dc_table; 1708 1709 if (state->identity.p1g) 1710 state->dc = dc_p1g_table; 1711 1712 /* fall through */ 1713 case CT_TUNER_STEP_0: 1714 dprintk("Start/continue DC calibration for %s path\n", 1715 (state->dc->i == 1) ? "I" : "Q"); 1716 dib0090_write_reg(state, 0x01, state->dc->bb1); 1717 dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7)); 1718 1719 state->step = 0; 1720 state->min_adc_diff = 1023; 1721 *tune_state = CT_TUNER_STEP_1; 1722 ret = 50; 1723 break; 1724 1725 case CT_TUNER_STEP_1: 1726 dib0090_set_trim(state); 1727 *tune_state = CT_TUNER_STEP_2; 1728 break; 1729 1730 case CT_TUNER_STEP_2: 1731 case CT_TUNER_STEP_3: 1732 case CT_TUNER_STEP_4: 1733 ret = dib0090_get_offset(state, tune_state); 1734 break; 1735 1736 case CT_TUNER_STEP_5: /* found an offset */ 1737 dprintk("adc_diff = %d, current step= %d\n", (u32) state->adc_diff, state->step); 1738 if (state->step == 0 && state->adc_diff < 0) { 1739 state->min_adc_diff = -1023; 1740 dprintk("Change of sign of the minimum adc diff\n"); 1741 } 1742 1743 dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d\n", state->adc_diff, state->min_adc_diff, state->step); 1744 1745 /* first turn for this frequency */ 1746 if (state->step == 0) { 1747 if (state->dc->pga && state->adc_diff < 0) 1748 state->step = 0x10; 1749 if (state->dc->pga == 0 && state->adc_diff > 0) 1750 state->step = 0x10; 1751 } 1752 1753 /* Look for a change of Sign in the Adc_diff.min_adc_diff is used to STORE the setp N-1 */ 1754 if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) { 1755 /* stop search when the delta the sign is changing and Steps =15 and Step=0 is force for continuance */ 1756 state->step++; 1757 state->min_adc_diff = state->adc_diff; 1758 *tune_state = CT_TUNER_STEP_1; 1759 } else { 1760 /* the minimum was what we have seen in the step before */ 1761 if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) { 1762 dprintk("Since adc_diff N = %d > adc_diff step N-1 = %d, Come back one step\n", state->adc_diff, state->min_adc_diff); 1763 state->step--; 1764 } 1765 1766 dib0090_set_trim(state); 1767 dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd\n", state->dc->addr, state->adc_diff, state->step); 1768 1769 state->dc++; 1770 if (state->dc->addr == 0) /* done */ 1771 *tune_state = CT_TUNER_STEP_6; 1772 else 1773 *tune_state = CT_TUNER_STEP_0; 1774 1775 } 1776 break; 1777 1778 case CT_TUNER_STEP_6: 1779 dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008); 1780 dib0090_write_reg(state, 0x1f, 0x7); 1781 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ 1782 state->calibrate &= ~DC_CAL; 1783 default: 1784 break; 1785 } 1786 return ret; 1787 } 1788 1789 static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state) 1790 { 1791 u8 wbd_gain; 1792 const struct dib0090_wbd_slope *wbd = state->current_wbd_table; 1793 1794 switch (*tune_state) { 1795 case CT_TUNER_START: 1796 while (state->current_rf / 1000 > wbd->max_freq) 1797 wbd++; 1798 if (wbd->wbd_gain != 0) 1799 wbd_gain = wbd->wbd_gain; 1800 else { 1801 wbd_gain = 4; 1802 #if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND) 1803 if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND)) 1804 wbd_gain = 2; 1805 #endif 1806 } 1807 1808 if (wbd_gain == state->wbd_calibration_gain) { /* the WBD calibration has already been done */ 1809 *tune_state = CT_TUNER_START; 1810 state->calibrate &= ~WBD_CAL; 1811 return 0; 1812 } 1813 1814 dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3)); 1815 1816 dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1))); 1817 *tune_state = CT_TUNER_STEP_0; 1818 state->wbd_calibration_gain = wbd_gain; 1819 return 90; /* wait for the WBDMUX to switch and for the ADC to sample */ 1820 1821 case CT_TUNER_STEP_0: 1822 state->wbd_offset = dib0090_get_slow_adc_val(state); 1823 dprintk("WBD calibration offset = %d\n", state->wbd_offset); 1824 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ 1825 state->calibrate &= ~WBD_CAL; 1826 break; 1827 1828 default: 1829 break; 1830 } 1831 return 0; 1832 } 1833 1834 static void dib0090_set_bandwidth(struct dib0090_state *state) 1835 { 1836 u16 tmp; 1837 1838 if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000) 1839 tmp = (3 << 14); 1840 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000) 1841 tmp = (2 << 14); 1842 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000) 1843 tmp = (1 << 14); 1844 else 1845 tmp = (0 << 14); 1846 1847 state->bb_1_def &= 0x3fff; 1848 state->bb_1_def |= tmp; 1849 1850 dib0090_write_reg(state, 0x01, state->bb_1_def); /* be sure that we have the right bb-filter */ 1851 1852 dib0090_write_reg(state, 0x03, 0x6008); /* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */ 1853 dib0090_write_reg(state, 0x04, 0x1); /* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */ 1854 if (state->identity.in_soc) { 1855 dib0090_write_reg(state, 0x05, 0x9bcf); /* attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 1 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 15 */ 1856 } else { 1857 dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f)); /* 22 = cap_value */ 1858 dib0090_write_reg(state, 0x05, 0xabcd); /* = 0xabcd : attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 2 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 13 */ 1859 } 1860 } 1861 1862 static const struct dib0090_pll dib0090_pll_table[] = { 1863 #ifdef CONFIG_BAND_CBAND 1864 {56000, 0, 9, 48, 6}, 1865 {70000, 1, 9, 48, 6}, 1866 {87000, 0, 8, 32, 4}, 1867 {105000, 1, 8, 32, 4}, 1868 {115000, 0, 7, 24, 6}, 1869 {140000, 1, 7, 24, 6}, 1870 {170000, 0, 6, 16, 4}, 1871 #endif 1872 #ifdef CONFIG_BAND_VHF 1873 {200000, 1, 6, 16, 4}, 1874 {230000, 0, 5, 12, 6}, 1875 {280000, 1, 5, 12, 6}, 1876 {340000, 0, 4, 8, 4}, 1877 {380000, 1, 4, 8, 4}, 1878 {450000, 0, 3, 6, 6}, 1879 #endif 1880 #ifdef CONFIG_BAND_UHF 1881 {580000, 1, 3, 6, 6}, 1882 {700000, 0, 2, 4, 4}, 1883 {860000, 1, 2, 4, 4}, 1884 #endif 1885 #ifdef CONFIG_BAND_LBAND 1886 {1800000, 1, 0, 2, 4}, 1887 #endif 1888 #ifdef CONFIG_BAND_SBAND 1889 {2900000, 0, 14, 1, 4}, 1890 #endif 1891 }; 1892 1893 static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = { 1894 1895 #ifdef CONFIG_BAND_CBAND 1896 {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, 1897 {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, 1898 {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, 1899 #endif 1900 #ifdef CONFIG_BAND_UHF 1901 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1902 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1903 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1904 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1905 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1906 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1907 #endif 1908 #ifdef CONFIG_BAND_LBAND 1909 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1910 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1911 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1912 #endif 1913 #ifdef CONFIG_BAND_SBAND 1914 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, 1915 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, 1916 #endif 1917 }; 1918 1919 static const struct dib0090_tuning dib0090_tuning_table[] = { 1920 1921 #ifdef CONFIG_BAND_CBAND 1922 {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, 1923 #endif 1924 #ifdef CONFIG_BAND_VHF 1925 {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, 1926 {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, 1927 {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, 1928 #endif 1929 #ifdef CONFIG_BAND_UHF 1930 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1931 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1932 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1933 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1934 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1935 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1936 #endif 1937 #ifdef CONFIG_BAND_LBAND 1938 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1939 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1940 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1941 #endif 1942 #ifdef CONFIG_BAND_SBAND 1943 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, 1944 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, 1945 #endif 1946 }; 1947 1948 static const struct dib0090_tuning dib0090_p1g_tuning_table[] = { 1949 #ifdef CONFIG_BAND_CBAND 1950 {170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB}, 1951 #endif 1952 #ifdef CONFIG_BAND_VHF 1953 {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, 1954 {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, 1955 {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, 1956 #endif 1957 #ifdef CONFIG_BAND_UHF 1958 {510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1959 {540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1960 {600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1961 {630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1962 {680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1963 {720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1964 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1965 #endif 1966 #ifdef CONFIG_BAND_LBAND 1967 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1968 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1969 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1970 #endif 1971 #ifdef CONFIG_BAND_SBAND 1972 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, 1973 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, 1974 #endif 1975 }; 1976 1977 static const struct dib0090_pll dib0090_p1g_pll_table[] = { 1978 #ifdef CONFIG_BAND_CBAND 1979 {57000, 0, 11, 48, 6}, 1980 {70000, 1, 11, 48, 6}, 1981 {86000, 0, 10, 32, 4}, 1982 {105000, 1, 10, 32, 4}, 1983 {115000, 0, 9, 24, 6}, 1984 {140000, 1, 9, 24, 6}, 1985 {170000, 0, 8, 16, 4}, 1986 #endif 1987 #ifdef CONFIG_BAND_VHF 1988 {200000, 1, 8, 16, 4}, 1989 {230000, 0, 7, 12, 6}, 1990 {280000, 1, 7, 12, 6}, 1991 {340000, 0, 6, 8, 4}, 1992 {380000, 1, 6, 8, 4}, 1993 {455000, 0, 5, 6, 6}, 1994 #endif 1995 #ifdef CONFIG_BAND_UHF 1996 {580000, 1, 5, 6, 6}, 1997 {680000, 0, 4, 4, 4}, 1998 {860000, 1, 4, 4, 4}, 1999 #endif 2000 #ifdef CONFIG_BAND_LBAND 2001 {1800000, 1, 2, 2, 4}, 2002 #endif 2003 #ifdef CONFIG_BAND_SBAND 2004 {2900000, 0, 1, 1, 6}, 2005 #endif 2006 }; 2007 2008 static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = { 2009 #ifdef CONFIG_BAND_CBAND 2010 {184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB}, 2011 {227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB}, 2012 {380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB}, 2013 #endif 2014 #ifdef CONFIG_BAND_UHF 2015 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 2016 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 2017 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 2018 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 2019 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 2020 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 2021 #endif 2022 #ifdef CONFIG_BAND_LBAND 2023 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 2024 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 2025 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 2026 #endif 2027 #ifdef CONFIG_BAND_SBAND 2028 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, 2029 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, 2030 #endif 2031 }; 2032 2033 static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = { 2034 #ifdef CONFIG_BAND_CBAND 2035 {300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB}, 2036 {380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB}, 2037 {570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB}, 2038 {858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB}, 2039 #endif 2040 }; 2041 2042 static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = { 2043 #ifdef CONFIG_BAND_CBAND 2044 { 300000, 0 , 3, 0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB }, 2045 { 380000, 0 , 10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB }, 2046 { 600000, 0 , 10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB }, 2047 { 660000, 0 , 5, 0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB }, 2048 { 720000, 0 , 5, 0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB }, 2049 { 860000, 0 , 4, 0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB }, 2050 #endif 2051 }; 2052 2053 int dib0090_update_tuning_table_7090(struct dvb_frontend *fe, 2054 u8 cfg_sensitivity) 2055 { 2056 struct dib0090_state *state = fe->tuner_priv; 2057 const struct dib0090_tuning *tune = 2058 dib0090_tuning_table_cband_7090e_sensitivity; 2059 const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = { 2060 { 300000, 0 , 3, 0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB }, 2061 { 650000, 0 , 4, 0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB }, 2062 { 860000, 0 , 5, 0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB }, 2063 }; 2064 2065 if ((!state->identity.p1g) || (!state->identity.in_soc) 2066 || ((state->identity.version != SOC_7090_P1G_21R1) 2067 && (state->identity.version != SOC_7090_P1G_11R1))) { 2068 dprintk("%s() function can only be used for dib7090\n", __func__); 2069 return -ENODEV; 2070 } 2071 2072 if (cfg_sensitivity) 2073 tune = dib0090_tuning_table_cband_7090e_sensitivity; 2074 else 2075 tune = dib0090_tuning_table_cband_7090e_aci; 2076 2077 while (state->rf_request > tune->max_freq) 2078 tune++; 2079 2080 dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000) 2081 | (tune->lna_bias & 0x7fff)); 2082 dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f) 2083 | ((tune->lna_tune << 6) & 0x07c0)); 2084 return 0; 2085 } 2086 EXPORT_SYMBOL(dib0090_update_tuning_table_7090); 2087 2088 static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state) 2089 { 2090 int ret = 0; 2091 u16 lo4 = 0xe900; 2092 2093 s16 adc_target; 2094 u16 adc; 2095 s8 step_sign; 2096 u8 force_soft_search = 0; 2097 2098 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1) 2099 force_soft_search = 1; 2100 2101 if (*tune_state == CT_TUNER_START) { 2102 dprintk("Start Captrim search : %s\n", 2103 (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO"); 2104 dib0090_write_reg(state, 0x10, 0x2B1); 2105 dib0090_write_reg(state, 0x1e, 0x0032); 2106 2107 if (!state->tuner_is_tuned) { 2108 /* prepare a complete captrim */ 2109 if (!state->identity.p1g || force_soft_search) 2110 state->step = state->captrim = state->fcaptrim = 64; 2111 2112 state->current_rf = state->rf_request; 2113 } else { /* we are already tuned to this frequency - the configuration is correct */ 2114 if (!state->identity.p1g || force_soft_search) { 2115 /* do a minimal captrim even if the frequency has not changed */ 2116 state->step = 4; 2117 state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f; 2118 } 2119 } 2120 state->adc_diff = 3000; 2121 *tune_state = CT_TUNER_STEP_0; 2122 2123 } else if (*tune_state == CT_TUNER_STEP_0) { 2124 if (state->identity.p1g && !force_soft_search) { 2125 u8 ratio = 31; 2126 2127 dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1); 2128 dib0090_read_reg(state, 0x40); 2129 ret = 50; 2130 } else { 2131 state->step /= 2; 2132 dib0090_write_reg(state, 0x18, lo4 | state->captrim); 2133 2134 if (state->identity.in_soc) 2135 ret = 25; 2136 } 2137 *tune_state = CT_TUNER_STEP_1; 2138 2139 } else if (*tune_state == CT_TUNER_STEP_1) { 2140 if (state->identity.p1g && !force_soft_search) { 2141 dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0); 2142 dib0090_read_reg(state, 0x40); 2143 2144 state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F; 2145 dprintk("***Final Captrim= 0x%x\n", state->fcaptrim); 2146 *tune_state = CT_TUNER_STEP_3; 2147 2148 } else { 2149 /* MERGE for all krosus before P1G */ 2150 adc = dib0090_get_slow_adc_val(state); 2151 dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV\n", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024); 2152 2153 if (state->rest == 0 || state->identity.in_soc) { /* Just for 8090P SOCS where auto captrim HW bug : TO CHECK IN ACI for SOCS !!! if 400 for 8090p SOC => tune issue !!! */ 2154 adc_target = 200; 2155 } else 2156 adc_target = 400; 2157 2158 if (adc >= adc_target) { 2159 adc -= adc_target; 2160 step_sign = -1; 2161 } else { 2162 adc = adc_target - adc; 2163 step_sign = 1; 2164 } 2165 2166 if (adc < state->adc_diff) { 2167 dprintk("CAPTRIM=%d is closer to target (%d/%d)\n", (u32) state->captrim, (u32) adc, (u32) state->adc_diff); 2168 state->adc_diff = adc; 2169 state->fcaptrim = state->captrim; 2170 } 2171 2172 state->captrim += step_sign * state->step; 2173 if (state->step >= 1) 2174 *tune_state = CT_TUNER_STEP_0; 2175 else 2176 *tune_state = CT_TUNER_STEP_2; 2177 2178 ret = 25; 2179 } 2180 } else if (*tune_state == CT_TUNER_STEP_2) { /* this step is only used by krosus < P1G */ 2181 /*write the final cptrim config */ 2182 dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim); 2183 2184 *tune_state = CT_TUNER_STEP_3; 2185 2186 } else if (*tune_state == CT_TUNER_STEP_3) { 2187 state->calibrate &= ~CAPTRIM_CAL; 2188 *tune_state = CT_TUNER_STEP_0; 2189 } 2190 2191 return ret; 2192 } 2193 2194 static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state) 2195 { 2196 int ret = 15; 2197 s16 val; 2198 2199 switch (*tune_state) { 2200 case CT_TUNER_START: 2201 state->wbdmux = dib0090_read_reg(state, 0x10); 2202 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3)); 2203 2204 state->bias = dib0090_read_reg(state, 0x13); 2205 dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8)); 2206 2207 *tune_state = CT_TUNER_STEP_0; 2208 /* wait for the WBDMUX to switch and for the ADC to sample */ 2209 break; 2210 2211 case CT_TUNER_STEP_0: 2212 state->adc_diff = dib0090_get_slow_adc_val(state); 2213 dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8)); 2214 *tune_state = CT_TUNER_STEP_1; 2215 break; 2216 2217 case CT_TUNER_STEP_1: 2218 val = dib0090_get_slow_adc_val(state); 2219 state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55; 2220 2221 dprintk("temperature: %d C\n", state->temperature - 30); 2222 2223 *tune_state = CT_TUNER_STEP_2; 2224 break; 2225 2226 case CT_TUNER_STEP_2: 2227 dib0090_write_reg(state, 0x13, state->bias); 2228 dib0090_write_reg(state, 0x10, state->wbdmux); /* write back original WBDMUX */ 2229 2230 *tune_state = CT_TUNER_START; 2231 state->calibrate &= ~TEMP_CAL; 2232 if (state->config->analog_output == 0) 2233 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14)); 2234 2235 break; 2236 2237 default: 2238 ret = 0; 2239 break; 2240 } 2241 return ret; 2242 } 2243 2244 #define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */ 2245 static int dib0090_tune(struct dvb_frontend *fe) 2246 { 2247 struct dib0090_state *state = fe->tuner_priv; 2248 const struct dib0090_tuning *tune = state->current_tune_table_index; 2249 const struct dib0090_pll *pll = state->current_pll_table_index; 2250 enum frontend_tune_state *tune_state = &state->tune_state; 2251 2252 u16 lo5, lo6, Den, tmp; 2253 u32 FBDiv, Rest, FREF, VCOF_kHz = 0; 2254 int ret = 10; /* 1ms is the default delay most of the time */ 2255 u8 c, i; 2256 2257 /************************* VCO ***************************/ 2258 /* Default values for FG */ 2259 /* from these are needed : */ 2260 /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv */ 2261 2262 /* in any case we first need to do a calibration if needed */ 2263 if (*tune_state == CT_TUNER_START) { 2264 /* deactivate DataTX before some calibrations */ 2265 if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL)) 2266 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14)); 2267 else 2268 /* Activate DataTX in case a calibration has been done before */ 2269 if (state->config->analog_output == 0) 2270 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14)); 2271 } 2272 2273 if (state->calibrate & DC_CAL) 2274 return dib0090_dc_offset_calibration(state, tune_state); 2275 else if (state->calibrate & WBD_CAL) { 2276 if (state->current_rf == 0) 2277 state->current_rf = state->fe->dtv_property_cache.frequency / 1000; 2278 return dib0090_wbd_calibration(state, tune_state); 2279 } else if (state->calibrate & TEMP_CAL) 2280 return dib0090_get_temperature(state, tune_state); 2281 else if (state->calibrate & CAPTRIM_CAL) 2282 return dib0090_captrim_search(state, tune_state); 2283 2284 if (*tune_state == CT_TUNER_START) { 2285 /* if soc and AGC pwm control, disengage mux to be able to R/W access to 0x01 register to set the right filter (cutoff_freq_select) during the tune sequence, otherwise, SOC SERPAR error when accessing to 0x01 */ 2286 if (state->config->use_pwm_agc && state->identity.in_soc) { 2287 tmp = dib0090_read_reg(state, 0x39); 2288 if ((tmp >> 10) & 0x1) 2289 dib0090_write_reg(state, 0x39, tmp & ~(1 << 10)); 2290 } 2291 2292 state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000); 2293 state->rf_request = 2294 state->fe->dtv_property_cache.frequency / 1000 + (state->current_band == 2295 BAND_UHF ? state->config->freq_offset_khz_uhf : state->config-> 2296 freq_offset_khz_vhf); 2297 2298 /* in ISDB-T 1seg we shift tuning frequency */ 2299 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1 2300 && state->fe->dtv_property_cache.isdbt_partial_reception == 0)) { 2301 const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if; 2302 u8 found_offset = 0; 2303 u32 margin_khz = 100; 2304 2305 if (LUT_offset != NULL) { 2306 while (LUT_offset->RF_freq != 0xffff) { 2307 if (((state->rf_request > (LUT_offset->RF_freq - margin_khz)) 2308 && (state->rf_request < (LUT_offset->RF_freq + margin_khz))) 2309 && LUT_offset->std == state->fe->dtv_property_cache.delivery_system) { 2310 state->rf_request += LUT_offset->offset_khz; 2311 found_offset = 1; 2312 break; 2313 } 2314 LUT_offset++; 2315 } 2316 } 2317 2318 if (found_offset == 0) 2319 state->rf_request += 400; 2320 } 2321 if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) { 2322 state->tuner_is_tuned = 0; 2323 state->current_rf = 0; 2324 state->current_standard = 0; 2325 2326 tune = dib0090_tuning_table; 2327 if (state->identity.p1g) 2328 tune = dib0090_p1g_tuning_table; 2329 2330 tmp = (state->identity.version >> 5) & 0x7; 2331 2332 if (state->identity.in_soc) { 2333 if (state->config->force_cband_input) { /* Use the CBAND input for all band */ 2334 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF 2335 || state->current_band & BAND_UHF) { 2336 state->current_band = BAND_CBAND; 2337 if (state->config->is_dib7090e) 2338 tune = dib0090_tuning_table_cband_7090e_sensitivity; 2339 else 2340 tune = dib0090_tuning_table_cband_7090; 2341 } 2342 } else { /* Use the CBAND input for all band under UHF */ 2343 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) { 2344 state->current_band = BAND_CBAND; 2345 if (state->config->is_dib7090e) 2346 tune = dib0090_tuning_table_cband_7090e_sensitivity; 2347 else 2348 tune = dib0090_tuning_table_cband_7090; 2349 } 2350 } 2351 } else 2352 if (tmp == 0x4 || tmp == 0x7) { 2353 /* CBAND tuner version for VHF */ 2354 if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) { 2355 state->current_band = BAND_CBAND; /* Force CBAND */ 2356 2357 tune = dib0090_tuning_table_fm_vhf_on_cband; 2358 if (state->identity.p1g) 2359 tune = dib0090_p1g_tuning_table_fm_vhf_on_cband; 2360 } 2361 } 2362 2363 pll = dib0090_pll_table; 2364 if (state->identity.p1g) 2365 pll = dib0090_p1g_pll_table; 2366 2367 /* Look for the interval */ 2368 while (state->rf_request > tune->max_freq) 2369 tune++; 2370 while (state->rf_request > pll->max_freq) 2371 pll++; 2372 2373 state->current_tune_table_index = tune; 2374 state->current_pll_table_index = pll; 2375 2376 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim)); 2377 2378 VCOF_kHz = (pll->hfdiv * state->rf_request) * 2; 2379 2380 FREF = state->config->io.clock_khz; 2381 if (state->config->fref_clock_ratio != 0) 2382 FREF /= state->config->fref_clock_ratio; 2383 2384 FBDiv = (VCOF_kHz / pll->topresc / FREF); 2385 Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF; 2386 2387 if (Rest < LPF) 2388 Rest = 0; 2389 else if (Rest < 2 * LPF) 2390 Rest = 2 * LPF; 2391 else if (Rest > (FREF - LPF)) { 2392 Rest = 0; 2393 FBDiv += 1; 2394 } else if (Rest > (FREF - 2 * LPF)) 2395 Rest = FREF - 2 * LPF; 2396 Rest = (Rest * 6528) / (FREF / 10); 2397 state->rest = Rest; 2398 2399 /* external loop filter, otherwise: 2400 * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4; 2401 * lo6 = 0x0e34 */ 2402 2403 if (Rest == 0) { 2404 if (pll->vco_band) 2405 lo5 = 0x049f; 2406 else 2407 lo5 = 0x041f; 2408 } else { 2409 if (pll->vco_band) 2410 lo5 = 0x049e; 2411 else if (state->config->analog_output) 2412 lo5 = 0x041d; 2413 else 2414 lo5 = 0x041c; 2415 } 2416 2417 if (state->identity.p1g) { /* Bias is done automatically in P1G */ 2418 if (state->identity.in_soc) { 2419 if (state->identity.version == SOC_8090_P1G_11R1) 2420 lo5 = 0x46f; 2421 else 2422 lo5 = 0x42f; 2423 } else 2424 lo5 = 0x42c; 2425 } 2426 2427 lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7); /* bit 15 is the split to the slave, we do not do it here */ 2428 2429 if (!state->config->io.pll_int_loop_filt) { 2430 if (state->identity.in_soc) 2431 lo6 = 0xff98; 2432 else if (state->identity.p1g || (Rest == 0)) 2433 lo6 = 0xfff8; 2434 else 2435 lo6 = 0xff28; 2436 } else 2437 lo6 = (state->config->io.pll_int_loop_filt << 3); 2438 2439 Den = 1; 2440 2441 if (Rest > 0) { 2442 if (state->config->analog_output) 2443 lo6 |= (1 << 2) | 2; 2444 else { 2445 if (state->identity.in_soc) 2446 lo6 |= (1 << 2) | 2; 2447 else 2448 lo6 |= (1 << 2) | 2; 2449 } 2450 Den = 255; 2451 } 2452 dib0090_write_reg(state, 0x15, (u16) FBDiv); 2453 if (state->config->fref_clock_ratio != 0) 2454 dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio); 2455 else 2456 dib0090_write_reg(state, 0x16, (Den << 8) | 1); 2457 dib0090_write_reg(state, 0x17, (u16) Rest); 2458 dib0090_write_reg(state, 0x19, lo5); 2459 dib0090_write_reg(state, 0x1c, lo6); 2460 2461 lo6 = tune->tuner_enable; 2462 if (state->config->analog_output) 2463 lo6 = (lo6 & 0xff9f) | 0x2; 2464 2465 dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL); 2466 2467 } 2468 2469 state->current_rf = state->rf_request; 2470 state->current_standard = state->fe->dtv_property_cache.delivery_system; 2471 2472 ret = 20; 2473 state->calibrate = CAPTRIM_CAL; /* captrim serach now */ 2474 } 2475 2476 else if (*tune_state == CT_TUNER_STEP_0) { /* Warning : because of captrim cal, if you change this step, change it also in _cal.c file because it is the step following captrim cal state machine */ 2477 const struct dib0090_wbd_slope *wbd = state->current_wbd_table; 2478 2479 while (state->current_rf / 1000 > wbd->max_freq) 2480 wbd++; 2481 2482 dib0090_write_reg(state, 0x1e, 0x07ff); 2483 dprintk("Final Captrim: %d\n", (u32) state->fcaptrim); 2484 dprintk("HFDIV code: %d\n", (u32) pll->hfdiv_code); 2485 dprintk("VCO = %d\n", (u32) pll->vco_band); 2486 dprintk("VCOF in kHz: %d ((%d*%d) << 1))\n", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request); 2487 dprintk("REFDIV: %d, FREF: %d\n", (u32) 1, (u32) state->config->io.clock_khz); 2488 dprintk("FBDIV: %d, Rest: %d\n", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17)); 2489 dprintk("Num: %d, Den: %d, SD: %d\n", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8), 2490 (u32) dib0090_read_reg(state, 0x1c) & 0x3); 2491 2492 #define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */ 2493 c = 4; 2494 i = 3; 2495 2496 if (wbd->wbd_gain != 0) 2497 c = wbd->wbd_gain; 2498 2499 state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1)); 2500 dib0090_write_reg(state, 0x10, state->wbdmux); 2501 2502 if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) { 2503 dprintk("P1G : The cable band is selected and lna_tune = %d\n", tune->lna_tune); 2504 dib0090_write_reg(state, 0x09, tune->lna_bias); 2505 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim)); 2506 } else 2507 dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias); 2508 2509 dib0090_write_reg(state, 0x0c, tune->v2i); 2510 dib0090_write_reg(state, 0x0d, tune->mix); 2511 dib0090_write_reg(state, 0x0e, tune->load); 2512 *tune_state = CT_TUNER_STEP_1; 2513 2514 } else if (*tune_state == CT_TUNER_STEP_1) { 2515 /* initialize the lt gain register */ 2516 state->rf_lt_def = 0x7c00; 2517 2518 dib0090_set_bandwidth(state); 2519 state->tuner_is_tuned = 1; 2520 2521 state->calibrate |= WBD_CAL; 2522 state->calibrate |= TEMP_CAL; 2523 *tune_state = CT_TUNER_STOP; 2524 } else 2525 ret = FE_CALLBACK_TIME_NEVER; 2526 return ret; 2527 } 2528 2529 static void dib0090_release(struct dvb_frontend *fe) 2530 { 2531 kfree(fe->tuner_priv); 2532 fe->tuner_priv = NULL; 2533 } 2534 2535 enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe) 2536 { 2537 struct dib0090_state *state = fe->tuner_priv; 2538 2539 return state->tune_state; 2540 } 2541 2542 EXPORT_SYMBOL(dib0090_get_tune_state); 2543 2544 int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) 2545 { 2546 struct dib0090_state *state = fe->tuner_priv; 2547 2548 state->tune_state = tune_state; 2549 return 0; 2550 } 2551 2552 EXPORT_SYMBOL(dib0090_set_tune_state); 2553 2554 static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency) 2555 { 2556 struct dib0090_state *state = fe->tuner_priv; 2557 2558 *frequency = 1000 * state->current_rf; 2559 return 0; 2560 } 2561 2562 static int dib0090_set_params(struct dvb_frontend *fe) 2563 { 2564 struct dib0090_state *state = fe->tuner_priv; 2565 u32 ret; 2566 2567 state->tune_state = CT_TUNER_START; 2568 2569 do { 2570 ret = dib0090_tune(fe); 2571 if (ret == FE_CALLBACK_TIME_NEVER) 2572 break; 2573 2574 /* 2575 * Despite dib0090_tune returns time at a 0.1 ms range, 2576 * the actual sleep time depends on CONFIG_HZ. The worse case 2577 * is when CONFIG_HZ=100. In such case, the minimum granularity 2578 * is 10ms. On some real field tests, the tuner sometimes don't 2579 * lock when this timer is lower than 10ms. So, enforce a 10ms 2580 * granularity and use usleep_range() instead of msleep(). 2581 */ 2582 ret = 10 * (ret + 99)/100; 2583 usleep_range(ret * 1000, (ret + 1) * 1000); 2584 } while (state->tune_state != CT_TUNER_STOP); 2585 2586 return 0; 2587 } 2588 2589 static const struct dvb_tuner_ops dib0090_ops = { 2590 .info = { 2591 .name = "DiBcom DiB0090", 2592 .frequency_min = 45000000, 2593 .frequency_max = 860000000, 2594 .frequency_step = 1000, 2595 }, 2596 .release = dib0090_release, 2597 2598 .init = dib0090_wakeup, 2599 .sleep = dib0090_sleep, 2600 .set_params = dib0090_set_params, 2601 .get_frequency = dib0090_get_frequency, 2602 }; 2603 2604 static const struct dvb_tuner_ops dib0090_fw_ops = { 2605 .info = { 2606 .name = "DiBcom DiB0090", 2607 .frequency_min = 45000000, 2608 .frequency_max = 860000000, 2609 .frequency_step = 1000, 2610 }, 2611 .release = dib0090_release, 2612 2613 .init = NULL, 2614 .sleep = NULL, 2615 .set_params = NULL, 2616 .get_frequency = NULL, 2617 }; 2618 2619 static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = { 2620 {470, 0, 250, 0, 100, 4}, 2621 {860, 51, 866, 21, 375, 4}, 2622 {1700, 0, 800, 0, 850, 4}, 2623 {2900, 0, 250, 0, 100, 6}, 2624 {0xFFFF, 0, 0, 0, 0, 0}, 2625 }; 2626 2627 struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) 2628 { 2629 struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL); 2630 if (st == NULL) 2631 return NULL; 2632 2633 st->config = config; 2634 st->i2c = i2c; 2635 st->fe = fe; 2636 mutex_init(&st->i2c_buffer_lock); 2637 fe->tuner_priv = st; 2638 2639 if (config->wbd == NULL) 2640 st->current_wbd_table = dib0090_wbd_table_default; 2641 else 2642 st->current_wbd_table = config->wbd; 2643 2644 if (dib0090_reset(fe) != 0) 2645 goto free_mem; 2646 2647 pr_info("DiB0090: successfully identified\n"); 2648 memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops)); 2649 2650 return fe; 2651 free_mem: 2652 kfree(st); 2653 fe->tuner_priv = NULL; 2654 return NULL; 2655 } 2656 2657 EXPORT_SYMBOL(dib0090_register); 2658 2659 struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) 2660 { 2661 struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL); 2662 if (st == NULL) 2663 return NULL; 2664 2665 st->config = config; 2666 st->i2c = i2c; 2667 st->fe = fe; 2668 mutex_init(&st->i2c_buffer_lock); 2669 fe->tuner_priv = st; 2670 2671 if (dib0090_fw_reset_digital(fe, st->config) != 0) 2672 goto free_mem; 2673 2674 dprintk("DiB0090 FW: successfully identified\n"); 2675 memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops)); 2676 2677 return fe; 2678 free_mem: 2679 kfree(st); 2680 fe->tuner_priv = NULL; 2681 return NULL; 2682 } 2683 EXPORT_SYMBOL(dib0090_fw_register); 2684 2685 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>"); 2686 MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>"); 2687 MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner"); 2688 MODULE_LICENSE("GPL"); 2689