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