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