1/* 2 * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner. 3 * 4 * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of the 9 * License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * 21 * 22 * This code is more or less generated from another driver, please 23 * excuse some codingstyle oddities. 24 * 25 */ 26 27#include <linux/kernel.h> 28#include <linux/slab.h> 29#include <linux/i2c.h> 30 31#include "dvb_frontend.h" 32 33#include "dib0090.h" 34#include "dibx000_common.h" 35 36static int debug; 37module_param(debug, int, 0644); 38MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); 39 40#define dprintk(args...) do { \ 41 if (debug) { \ 42 printk(KERN_DEBUG "DiB0090: "); \ 43 printk(args); \ 44 printk("\n"); \ 45 } \ 46} while (0) 47 48#define CONFIG_SYS_ISDBT 49#define CONFIG_BAND_CBAND 50#define CONFIG_BAND_VHF 51#define CONFIG_BAND_UHF 52#define CONFIG_DIB0090_USE_PWM_AGC 53 54#define EN_LNA0 0x8000 55#define EN_LNA1 0x4000 56#define EN_LNA2 0x2000 57#define EN_LNA3 0x1000 58#define EN_MIX0 0x0800 59#define EN_MIX1 0x0400 60#define EN_MIX2 0x0200 61#define EN_MIX3 0x0100 62#define EN_IQADC 0x0040 63#define EN_PLL 0x0020 64#define EN_TX 0x0010 65#define EN_BB 0x0008 66#define EN_LO 0x0004 67#define EN_BIAS 0x0001 68 69#define EN_IQANA 0x0002 70#define EN_DIGCLK 0x0080 /* not in the 0x24 reg, only in 0x1b */ 71#define EN_CRYSTAL 0x0002 72 73#define EN_UHF 0x22E9 74#define EN_VHF 0x44E9 75#define EN_LBD 0x11E9 76#define EN_SBD 0x44E9 77#define EN_CAB 0x88E9 78 79#define pgm_read_word(w) (*w) 80 81struct dc_calibration; 82 83struct dib0090_tuning { 84 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ 85 u8 switch_trim; 86 u8 lna_tune; 87 u8 lna_bias; 88 u16 v2i; 89 u16 mix; 90 u16 load; 91 u16 tuner_enable; 92}; 93 94struct dib0090_pll { 95 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ 96 u8 vco_band; 97 u8 hfdiv_code; 98 u8 hfdiv; 99 u8 topresc; 100}; 101 102struct dib0090_state { 103 struct i2c_adapter *i2c; 104 struct dvb_frontend *fe; 105 const struct dib0090_config *config; 106 107 u8 current_band; 108 u16 revision; 109 enum frontend_tune_state tune_state; 110 u32 current_rf; 111 112 u16 wbd_offset; 113 s16 wbd_target; /* in dB */ 114 115 s16 rf_gain_limit; /* take-over-point: where to split between bb and rf gain */ 116 s16 current_gain; /* keeps the currently programmed gain */ 117 u8 agc_step; /* new binary search */ 118 119 u16 gain[2]; /* for channel monitoring */ 120 121 const u16 *rf_ramp; 122 const u16 *bb_ramp; 123 124 /* for the software AGC ramps */ 125 u16 bb_1_def; 126 u16 rf_lt_def; 127 u16 gain_reg[4]; 128 129 /* for the captrim/dc-offset search */ 130 s8 step; 131 s16 adc_diff; 132 s16 min_adc_diff; 133 134 s8 captrim; 135 s8 fcaptrim; 136 137 const struct dc_calibration *dc; 138 u16 bb6, bb7; 139 140 const struct dib0090_tuning *current_tune_table_index; 141 const struct dib0090_pll *current_pll_table_index; 142 143 u8 tuner_is_tuned; 144 u8 agc_freeze; 145 146 u8 reset; 147}; 148 149static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) 150{ 151 u8 b[2]; 152 struct i2c_msg msg[2] = { 153 {.addr = state->config->i2c_address, .flags = 0, .buf = ®, .len = 1}, 154 {.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2}, 155 }; 156 if (i2c_transfer(state->i2c, msg, 2) != 2) { 157 printk(KERN_WARNING "DiB0090 I2C read failed\n"); 158 return 0; 159 } 160 return (b[0] << 8) | b[1]; 161} 162 163static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) 164{ 165 u8 b[3] = { reg & 0xff, val >> 8, val & 0xff }; 166 struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 }; 167 if (i2c_transfer(state->i2c, &msg, 1) != 1) { 168 printk(KERN_WARNING "DiB0090 I2C write failed\n"); 169 return -EREMOTEIO; 170 } 171 return 0; 172} 173 174#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) 175#define ADC_TARGET -220 176#define GAIN_ALPHA 5 177#define WBD_ALPHA 6 178#define LPF 100 179static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c) 180{ 181 do { 182 dib0090_write_reg(state, r++, *b++); 183 } while (--c); 184} 185 186static u16 dib0090_identify(struct dvb_frontend *fe) 187{ 188 struct dib0090_state *state = fe->tuner_priv; 189 u16 v; 190 191 v = dib0090_read_reg(state, 0x1a); 192 193#ifdef FIRMWARE_FIREFLY 194 /* pll is not locked locked */ 195 if (!(v & 0x800)) 196 dprintk("FE%d : Identification : pll is not yet locked", fe->id); 197#endif 198 199 /* without PLL lock info */ 200 v &= 0x3ff; 201 dprintk("P/V: %04x:", v); 202 203 if ((v >> 8) & 0xf) 204 dprintk("FE%d : Product ID = 0x%x : KROSUS", fe->id, (v >> 8) & 0xf); 205 else 206 return 0xff; 207 208 v &= 0xff; 209 if (((v >> 5) & 0x7) == 0x1) 210 dprintk("FE%d : MP001 : 9090/8096", fe->id); 211 else if (((v >> 5) & 0x7) == 0x4) 212 dprintk("FE%d : MP005 : Single Sband", fe->id); 213 else if (((v >> 5) & 0x7) == 0x6) 214 dprintk("FE%d : MP008 : diversity VHF-UHF-LBAND", fe->id); 215 else if (((v >> 5) & 0x7) == 0x7) 216 dprintk("FE%d : MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND", fe->id); 217 else 218 return 0xff; 219 220 /* revision only */ 221 if ((v & 0x1f) == 0x3) 222 dprintk("FE%d : P1-D/E/F detected", fe->id); 223 else if ((v & 0x1f) == 0x1) 224 dprintk("FE%d : P1C detected", fe->id); 225 else if ((v & 0x1f) == 0x0) { 226#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT 227 dprintk("FE%d : P1-A/B detected: using previous driver - support will be removed soon", fe->id); 228 dib0090_p1b_register(fe); 229#else 230 dprintk("FE%d : P1-A/B detected: driver is deactivated - not available", fe->id); 231 return 0xff; 232#endif 233 } 234 235 return v; 236} 237 238static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg) 239{ 240 struct dib0090_state *state = fe->tuner_priv; 241 242 HARD_RESET(state); 243 244 dib0090_write_reg(state, 0x24, EN_PLL); 245 dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */ 246 247 /* adcClkOutRatio=8->7, release reset */ 248 dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0); 249 if (cfg->clkoutdrive != 0) 250 dib0090_write_reg(state, 0x23, 251 (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (cfg->clkoutdrive << 5) | (cfg-> 252 clkouttobamse 253 << 4) | (0 254 << 255 2) 256 | (0)); 257 else 258 dib0090_write_reg(state, 0x23, 259 (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (7 << 5) | (cfg-> 260 clkouttobamse << 4) | (0 261 << 262 2) 263 | (0)); 264 265 /* enable pll, de-activate reset, ratio: 2/1 = 60MHz */ 266 dib0090_write_reg(state, 0x21, 267 (cfg->io.pll_bypass << 15) | (1 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)); 268 269} 270 271static int dib0090_wakeup(struct dvb_frontend *fe) 272{ 273 struct dib0090_state *state = fe->tuner_priv; 274 if (state->config->sleep) 275 state->config->sleep(fe, 0); 276 return 0; 277} 278 279static int dib0090_sleep(struct dvb_frontend *fe) 280{ 281 struct dib0090_state *state = fe->tuner_priv; 282 if (state->config->sleep) 283 state->config->sleep(fe, 1); 284 return 0; 285} 286 287void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast) 288{ 289 struct dib0090_state *state = fe->tuner_priv; 290 if (fast) 291 dib0090_write_reg(state, 0x04, 0); 292 else 293 dib0090_write_reg(state, 0x04, 1); 294} 295EXPORT_SYMBOL(dib0090_dcc_freq); 296 297static const u16 rf_ramp_pwm_cband[] = { 298 0, /* max RF gain in 10th of dB */ 299 0, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */ 300 0, /* ramp_max = maximum X used on the ramp */ 301 (0 << 10) | 0, /* 0x2c, LNA 1 = 0dB */ 302 (0 << 10) | 0, /* 0x2d, LNA 1 */ 303 (0 << 10) | 0, /* 0x2e, LNA 2 = 0dB */ 304 (0 << 10) | 0, /* 0x2f, LNA 2 */ 305 (0 << 10) | 0, /* 0x30, LNA 3 = 0dB */ 306 (0 << 10) | 0, /* 0x31, LNA 3 */ 307 (0 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */ 308 (0 << 10) | 0, /* GAIN_4_2, LNA 4 */ 309}; 310 311static const u16 rf_ramp_vhf[] = { 312 412, /* max RF gain in 10th of dB */ 313 132, 307, 127, /* LNA1, 13.2dB */ 314 105, 412, 255, /* LNA2, 10.5dB */ 315 50, 50, 127, /* LNA3, 5dB */ 316 125, 175, 127, /* LNA4, 12.5dB */ 317 0, 0, 127, /* CBAND, 0dB */ 318}; 319 320static const u16 rf_ramp_uhf[] = { 321 412, /* max RF gain in 10th of dB */ 322 132, 307, 127, /* LNA1 : total gain = 13.2dB, point on the ramp where this amp is full gain, value to write to get full gain */ 323 105, 412, 255, /* LNA2 : 10.5 dB */ 324 50, 50, 127, /* LNA3 : 5.0 dB */ 325 125, 175, 127, /* LNA4 : 12.5 dB */ 326 0, 0, 127, /* CBAND : 0.0 dB */ 327}; 328 329static const u16 rf_ramp_cband[] = { 330 332, /* max RF gain in 10th of dB */ 331 132, 252, 127, /* LNA1, dB */ 332 80, 332, 255, /* LNA2, dB */ 333 0, 0, 127, /* LNA3, dB */ 334 0, 0, 127, /* LNA4, dB */ 335 120, 120, 127, /* LT1 CBAND */ 336}; 337 338static const u16 rf_ramp_pwm_vhf[] = { 339 404, /* max RF gain in 10th of dB */ 340 25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */ 341 1011, /* ramp_max = maximum X used on the ramp */ 342 (6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */ 343 (0 << 10) | 756, /* 0x2d, LNA 1 */ 344 (16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */ 345 (0 << 10) | 1011, /* 0x2f, LNA 2 */ 346 (16 << 10) | 290, /* 0x30, LNA 3 = 5dB */ 347 (0 << 10) | 417, /* 0x31, LNA 3 */ 348 (7 << 10) | 0, /* GAIN_4_1, LNA 4 = 12.5dB */ 349 (0 << 10) | 290, /* GAIN_4_2, LNA 4 */ 350}; 351 352static const u16 rf_ramp_pwm_uhf[] = { 353 404, /* max RF gain in 10th of dB */ 354 25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */ 355 1011, /* ramp_max = maximum X used on the ramp */ 356 (6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */ 357 (0 << 10) | 756, /* 0x2d, LNA 1 */ 358 (16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */ 359 (0 << 10) | 1011, /* 0x2f, LNA 2 */ 360 (16 << 10) | 0, /* 0x30, LNA 3 = 5dB */ 361 (0 << 10) | 127, /* 0x31, LNA 3 */ 362 (7 << 10) | 127, /* GAIN_4_1, LNA 4 = 12.5dB */ 363 (0 << 10) | 417, /* GAIN_4_2, LNA 4 */ 364}; 365 366static const u16 bb_ramp_boost[] = { 367 550, /* max BB gain in 10th of dB */ 368 260, 260, 26, /* BB1, 26dB */ 369 290, 550, 29, /* BB2, 29dB */ 370}; 371 372static const u16 bb_ramp_pwm_normal[] = { 373 500, /* max RF gain in 10th of dB */ 374 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x34 */ 375 400, 376 (2 << 9) | 0, /* 0x35 = 21dB */ 377 (0 << 9) | 168, /* 0x36 */ 378 (2 << 9) | 168, /* 0x37 = 29dB */ 379 (0 << 9) | 400, /* 0x38 */ 380}; 381 382struct slope { 383 int16_t range; 384 int16_t slope; 385}; 386static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val) 387{ 388 u8 i; 389 u16 rest; 390 u16 ret = 0; 391 for (i = 0; i < num; i++) { 392 if (val > slopes[i].range) 393 rest = slopes[i].range; 394 else 395 rest = val; 396 ret += (rest * slopes[i].slope) / slopes[i].range; 397 val -= rest; 398 } 399 return ret; 400} 401 402static const struct slope dib0090_wbd_slopes[3] = { 403 {66, 120}, /* -64,-52: offset - 65 */ 404 {600, 170}, /* -52,-35: 65 - 665 */ 405 {170, 250}, /* -45,-10: 665 - 835 */ 406}; 407 408static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd) 409{ 410 wbd &= 0x3ff; 411 if (wbd < state->wbd_offset) 412 wbd = 0; 413 else 414 wbd -= state->wbd_offset; 415 /* -64dB is the floor */ 416 return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd); 417} 418 419static void dib0090_wbd_target(struct dib0090_state *state, u32 rf) 420{ 421 u16 offset = 250; 422 423 /* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */ 424 425 if (state->current_band == BAND_VHF) 426 offset = 650; 427#ifndef FIRMWARE_FIREFLY 428 if (state->current_band == BAND_VHF) 429 offset = state->config->wbd_vhf_offset; 430 if (state->current_band == BAND_CBAND) 431 offset = state->config->wbd_cband_offset; 432#endif 433 434 state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset); 435 dprintk("wbd-target: %d dB", (u32) state->wbd_target); 436} 437 438static const int gain_reg_addr[4] = { 439 0x08, 0x0a, 0x0f, 0x01 440}; 441 442static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force) 443{ 444 u16 rf, bb, ref; 445 u16 i, v, gain_reg[4] = { 0 }, gain; 446 const u16 *g; 447 448 if (top_delta < -511) 449 top_delta = -511; 450 if (top_delta > 511) 451 top_delta = 511; 452 453 if (force) { 454 top_delta *= (1 << WBD_ALPHA); 455 gain_delta *= (1 << GAIN_ALPHA); 456 } 457 458 if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit)) /* overflow */ 459 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA; 460 else 461 state->rf_gain_limit += top_delta; 462 463 if (state->rf_gain_limit < 0) /*underflow */ 464 state->rf_gain_limit = 0; 465 466 /* use gain as a temporary variable and correct current_gain */ 467 gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA; 468 if (gain_delta >= ((s16) gain - state->current_gain)) /* overflow */ 469 state->current_gain = gain; 470 else 471 state->current_gain += gain_delta; 472 /* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */ 473 if (state->current_gain < 0) 474 state->current_gain = 0; 475 476 /* now split total gain to rf and bb gain */ 477 gain = state->current_gain >> GAIN_ALPHA; 478 479 /* requested gain is bigger than rf gain limit - ACI/WBD adjustment */ 480 if (gain > (state->rf_gain_limit >> WBD_ALPHA)) { 481 rf = state->rf_gain_limit >> WBD_ALPHA; 482 bb = gain - rf; 483 if (bb > state->bb_ramp[0]) 484 bb = state->bb_ramp[0]; 485 } else { /* high signal level -> all gains put on RF */ 486 rf = gain; 487 bb = 0; 488 } 489 490 state->gain[0] = rf; 491 state->gain[1] = bb; 492 493 /* software ramp */ 494 /* Start with RF gains */ 495 g = state->rf_ramp + 1; /* point on RF LNA1 max gain */ 496 ref = rf; 497 for (i = 0; i < 7; i++) { /* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */ 498 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 */ 499 v = 0; /* force the gain to write for the current amp to be null */ 500 else if (ref >= g[1]) /* Gain to set is higher than the high working point of this amp */ 501 v = g[2]; /* force this amp to be full gain */ 502 else /* compute the value to set to this amp because we are somewhere in his range */ 503 v = ((ref - (g[1] - g[0])) * g[2]) / g[0]; 504 505 if (i == 0) /* LNA 1 reg mapping */ 506 gain_reg[0] = v; 507 else if (i == 1) /* LNA 2 reg mapping */ 508 gain_reg[0] |= v << 7; 509 else if (i == 2) /* LNA 3 reg mapping */ 510 gain_reg[1] = v; 511 else if (i == 3) /* LNA 4 reg mapping */ 512 gain_reg[1] |= v << 7; 513 else if (i == 4) /* CBAND LNA reg mapping */ 514 gain_reg[2] = v | state->rf_lt_def; 515 else if (i == 5) /* BB gain 1 reg mapping */ 516 gain_reg[3] = v << 3; 517 else if (i == 6) /* BB gain 2 reg mapping */ 518 gain_reg[3] |= v << 8; 519 520 g += 3; /* go to next gain bloc */ 521 522 /* When RF is finished, start with BB */ 523 if (i == 4) { 524 g = state->bb_ramp + 1; /* point on BB gain 1 max gain */ 525 ref = bb; 526 } 527 } 528 gain_reg[3] |= state->bb_1_def; 529 gain_reg[3] |= ((bb % 10) * 100) / 125; 530 531#ifdef DEBUG_AGC 532 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", rf, bb, rf + bb, 533 gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]); 534#endif 535 536 /* Write the amplifier regs */ 537 for (i = 0; i < 4; i++) { 538 v = gain_reg[i]; 539 if (force || state->gain_reg[i] != v) { 540 state->gain_reg[i] = v; 541 dib0090_write_reg(state, gain_reg_addr[i], v); 542 } 543 } 544} 545 546static void dib0090_set_boost(struct dib0090_state *state, int onoff) 547{ 548 state->bb_1_def &= 0xdfff; 549 state->bb_1_def |= onoff << 13; 550} 551 552static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg) 553{ 554 state->rf_ramp = cfg; 555} 556 557static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg) 558{ 559 state->rf_ramp = cfg; 560 561 dib0090_write_reg(state, 0x2a, 0xffff); 562 563 dprintk("total RF gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x2a)); 564 565 dib0090_write_regs(state, 0x2c, cfg + 3, 6); 566 dib0090_write_regs(state, 0x3e, cfg + 9, 2); 567} 568 569static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg) 570{ 571 state->bb_ramp = cfg; 572 dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */ 573} 574 575static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg) 576{ 577 state->bb_ramp = cfg; 578 579 dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */ 580 581 dib0090_write_reg(state, 0x33, 0xffff); 582 dprintk("total BB gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x33)); 583 dib0090_write_regs(state, 0x35, cfg + 3, 4); 584} 585 586void dib0090_pwm_gain_reset(struct dvb_frontend *fe) 587{ 588 struct dib0090_state *state = fe->tuner_priv; 589 /* reset the AGC */ 590 591 if (state->config->use_pwm_agc) { 592#ifdef CONFIG_BAND_SBAND 593 if (state->current_band == BAND_SBAND) { 594 dib0090_set_rframp_pwm(state, rf_ramp_pwm_sband); 595 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_boost); 596 } else 597#endif 598#ifdef CONFIG_BAND_CBAND 599 if (state->current_band == BAND_CBAND) { 600 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband); 601 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); 602 } else 603#endif 604#ifdef CONFIG_BAND_VHF 605 if (state->current_band == BAND_VHF) { 606 dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf); 607 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); 608 } else 609#endif 610 { 611 dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf); 612 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); 613 } 614 615 if (state->rf_ramp[0] != 0) 616 dib0090_write_reg(state, 0x32, (3 << 11)); 617 else 618 dib0090_write_reg(state, 0x32, (0 << 11)); 619 620 dib0090_write_reg(state, 0x39, (1 << 10)); 621 } 622} 623EXPORT_SYMBOL(dib0090_pwm_gain_reset); 624 625int dib0090_gain_control(struct dvb_frontend *fe) 626{ 627 struct dib0090_state *state = fe->tuner_priv; 628 enum frontend_tune_state *tune_state = &state->tune_state; 629 int ret = 10; 630 631 u16 wbd_val = 0; 632 u8 apply_gain_immediatly = 1; 633 s16 wbd_error = 0, adc_error = 0; 634 635 if (*tune_state == CT_AGC_START) { 636 state->agc_freeze = 0; 637 dib0090_write_reg(state, 0x04, 0x0); 638 639#ifdef CONFIG_BAND_SBAND 640 if (state->current_band == BAND_SBAND) { 641 dib0090_set_rframp(state, rf_ramp_sband); 642 dib0090_set_bbramp(state, bb_ramp_boost); 643 } else 644#endif 645#ifdef CONFIG_BAND_VHF 646 if (state->current_band == BAND_VHF) { 647 dib0090_set_rframp(state, rf_ramp_vhf); 648 dib0090_set_bbramp(state, bb_ramp_boost); 649 } else 650#endif 651#ifdef CONFIG_BAND_CBAND 652 if (state->current_band == BAND_CBAND) { 653 dib0090_set_rframp(state, rf_ramp_cband); 654 dib0090_set_bbramp(state, bb_ramp_boost); 655 } else 656#endif 657 { 658 dib0090_set_rframp(state, rf_ramp_uhf); 659 dib0090_set_bbramp(state, bb_ramp_boost); 660 } 661 662 dib0090_write_reg(state, 0x32, 0); 663 dib0090_write_reg(state, 0x39, 0); 664 665 dib0090_wbd_target(state, state->current_rf); 666 667 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA; 668 state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA; 669 670 *tune_state = CT_AGC_STEP_0; 671 } else if (!state->agc_freeze) { 672 s16 wbd; 673 674 int adc; 675 wbd_val = dib0090_read_reg(state, 0x1d); 676 677 /* read and calc the wbd power */ 678 wbd = dib0090_wbd_to_db(state, wbd_val); 679 wbd_error = state->wbd_target - wbd; 680 681 if (*tune_state == CT_AGC_STEP_0) { 682 if (wbd_error < 0 && state->rf_gain_limit > 0) { 683#ifdef CONFIG_BAND_CBAND 684 /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */ 685 u8 ltg2 = (state->rf_lt_def >> 10) & 0x7; 686 if (state->current_band == BAND_CBAND && ltg2) { 687 ltg2 >>= 1; 688 state->rf_lt_def &= ltg2 << 10; /* reduce in 3 steps from 7 to 0 */ 689 } 690#endif 691 } else { 692 state->agc_step = 0; 693 *tune_state = CT_AGC_STEP_1; 694 } 695 } else { 696 /* calc the adc power */ 697 adc = state->config->get_adc_power(fe); 698 adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21; /* included in [0:-700] */ 699 700 adc_error = (s16) (((s32) ADC_TARGET) - adc); 701#ifdef CONFIG_STANDARD_DAB 702 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) 703 adc_error += 130; 704#endif 705#ifdef CONFIG_STANDARD_DVBT 706 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT && 707 (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16)) 708 adc_error += 60; 709#endif 710#ifdef CONFIG_SYS_ISDBT 711 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count > 712 0) 713 && 714 ((state->fe->dtv_property_cache.layer[0].modulation == 715 QAM_64) 716 || (state->fe->dtv_property_cache.layer[0]. 717 modulation == QAM_16))) 718 || 719 ((state->fe->dtv_property_cache.layer[1].segment_count > 720 0) 721 && 722 ((state->fe->dtv_property_cache.layer[1].modulation == 723 QAM_64) 724 || (state->fe->dtv_property_cache.layer[1]. 725 modulation == QAM_16))) 726 || 727 ((state->fe->dtv_property_cache.layer[2].segment_count > 728 0) 729 && 730 ((state->fe->dtv_property_cache.layer[2].modulation == 731 QAM_64) 732 || (state->fe->dtv_property_cache.layer[2]. 733 modulation == QAM_16))) 734 ) 735 ) 736 adc_error += 60; 737#endif 738 739 if (*tune_state == CT_AGC_STEP_1) { /* quickly go to the correct range of the ADC power */ 740 if (ABS(adc_error) < 50 || state->agc_step++ > 5) { 741 742#ifdef CONFIG_STANDARD_DAB 743 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) { 744 dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63)); /* cap value = 63 : narrow BB filter : Fc = 1.8MHz */ 745 dib0090_write_reg(state, 0x04, 0x0); 746 } else 747#endif 748 { 749 dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32)); 750 dib0090_write_reg(state, 0x04, 0x01); /*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */ 751 } 752 753 *tune_state = CT_AGC_STOP; 754 } 755 } else { 756 /* everything higher than or equal to CT_AGC_STOP means tracking */ 757 ret = 100; /* 10ms interval */ 758 apply_gain_immediatly = 0; 759 } 760 } 761#ifdef DEBUG_AGC 762 dprintk 763 ("FE: %d, tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm", 764 (u32) fe->id, (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val, 765 (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA)); 766#endif 767 } 768 769 /* apply gain */ 770 if (!state->agc_freeze) 771 dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly); 772 return ret; 773} 774EXPORT_SYMBOL(dib0090_gain_control); 775 776void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt) 777{ 778 struct dib0090_state *state = fe->tuner_priv; 779 if (rf) 780 *rf = state->gain[0]; 781 if (bb) 782 *bb = state->gain[1]; 783 if (rf_gain_limit) 784 *rf_gain_limit = state->rf_gain_limit; 785 if (rflt) 786 *rflt = (state->rf_lt_def >> 10) & 0x7; 787} 788EXPORT_SYMBOL(dib0090_get_current_gain); 789 790u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner) 791{ 792 struct dib0090_state *st = tuner->tuner_priv; 793 return st->wbd_offset; 794} 795EXPORT_SYMBOL(dib0090_get_wbd_offset); 796 797static const u16 dib0090_defaults[] = { 798 799 25, 0x01, 800 0x0000, 801 0x99a0, 802 0x6008, 803 0x0000, 804 0x8acb, 805 0x0000, 806 0x0405, 807 0x0000, 808 0x0000, 809 0x0000, 810 0xb802, 811 0x0300, 812 0x2d12, 813 0xbac0, 814 0x7c00, 815 0xdbb9, 816 0x0954, 817 0x0743, 818 0x8000, 819 0x0001, 820 0x0040, 821 0x0100, 822 0x0000, 823 0xe910, 824 0x149e, 825 826 1, 0x1c, 827 0xff2d, 828 829 1, 0x39, 830 0x0000, 831 832 1, 0x1b, 833 EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL, 834 2, 0x1e, 835 0x07FF, 836 0x0007, 837 838 1, 0x24, 839 EN_UHF | EN_CRYSTAL, 840 841 2, 0x3c, 842 0x3ff, 843 0x111, 844 0 845}; 846 847static int dib0090_reset(struct dvb_frontend *fe) 848{ 849 struct dib0090_state *state = fe->tuner_priv; 850 u16 l, r, *n; 851 852 dib0090_reset_digital(fe, state->config); 853 state->revision = dib0090_identify(fe); 854 855 /* Revision definition */ 856 if (state->revision == 0xff) 857 return -EINVAL; 858#ifdef EFUSE 859 else if ((state->revision & 0x1f) >= 3) /* Update the efuse : Only available for KROSUS > P1C */ 860 dib0090_set_EFUSE(state); 861#endif 862 863#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT 864 if (!(state->revision & 0x1)) /* it is P1B - reset is already done */ 865 return 0; 866#endif 867 868 /* Upload the default values */ 869 n = (u16 *) dib0090_defaults; 870 l = pgm_read_word(n++); 871 while (l) { 872 r = pgm_read_word(n++); 873 do { 874 /* DEBUG_TUNER */ 875 /* dprintk("%d, %d, %d", l, r, pgm_read_word(n)); */ 876 dib0090_write_reg(state, r, pgm_read_word(n++)); 877 r++; 878 } while (--l); 879 l = pgm_read_word(n++); 880 } 881 882 /* Congigure in function of the crystal */ 883 if (state->config->io.clock_khz >= 24000) 884 l = 1; 885 else 886 l = 2; 887 dib0090_write_reg(state, 0x14, l); 888 dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1); 889 890 state->reset = 3; /* enable iq-offset-calibration and wbd-calibration when tuning next time */ 891 892 return 0; 893} 894 895#define steps(u) (((u) > 15) ? ((u)-16) : (u)) 896#define INTERN_WAIT 10 897static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state) 898{ 899 int ret = INTERN_WAIT * 10; 900 901 switch (*tune_state) { 902 case CT_TUNER_STEP_2: 903 /* Turns to positive */ 904 dib0090_write_reg(state, 0x1f, 0x7); 905 *tune_state = CT_TUNER_STEP_3; 906 break; 907 908 case CT_TUNER_STEP_3: 909 state->adc_diff = dib0090_read_reg(state, 0x1d); 910 911 /* Turns to negative */ 912 dib0090_write_reg(state, 0x1f, 0x4); 913 *tune_state = CT_TUNER_STEP_4; 914 break; 915 916 case CT_TUNER_STEP_4: 917 state->adc_diff -= dib0090_read_reg(state, 0x1d); 918 *tune_state = CT_TUNER_STEP_5; 919 ret = 0; 920 break; 921 922 default: 923 break; 924 } 925 926 return ret; 927} 928 929struct dc_calibration { 930 uint8_t addr; 931 uint8_t offset; 932 uint8_t pga:1; 933 uint16_t bb1; 934 uint8_t i:1; 935}; 936 937static const struct dc_calibration dc_table[] = { 938 /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */ 939 {0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1}, 940 {0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0}, 941 /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */ 942 {0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1}, 943 {0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0}, 944 {0}, 945}; 946 947static void dib0090_set_trim(struct dib0090_state *state) 948{ 949 u16 *val; 950 951 if (state->dc->addr == 0x07) 952 val = &state->bb7; 953 else 954 val = &state->bb6; 955 956 *val &= ~(0x1f << state->dc->offset); 957 *val |= state->step << state->dc->offset; 958 959 dib0090_write_reg(state, state->dc->addr, *val); 960} 961 962static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state) 963{ 964 int ret = 0; 965 966 switch (*tune_state) { 967 968 case CT_TUNER_START: 969 /* init */ 970 dprintk("Internal DC calibration"); 971 972 /* the LNA is off */ 973 dib0090_write_reg(state, 0x24, 0x02ed); 974 975 /* force vcm2 = 0.8V */ 976 state->bb6 = 0; 977 state->bb7 = 0x040d; 978 979 state->dc = dc_table; 980 981 *tune_state = CT_TUNER_STEP_0; 982 983 /* fall through */ 984 985 case CT_TUNER_STEP_0: 986 dib0090_write_reg(state, 0x01, state->dc->bb1); 987 dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7)); 988 989 state->step = 0; 990 991 state->min_adc_diff = 1023; 992 993 *tune_state = CT_TUNER_STEP_1; 994 ret = 50; 995 break; 996 997 case CT_TUNER_STEP_1: 998 dib0090_set_trim(state); 999 1000 *tune_state = CT_TUNER_STEP_2; 1001 break; 1002 1003 case CT_TUNER_STEP_2: 1004 case CT_TUNER_STEP_3: 1005 case CT_TUNER_STEP_4: 1006 ret = dib0090_get_offset(state, tune_state); 1007 break; 1008 1009 case CT_TUNER_STEP_5: /* found an offset */ 1010 dprintk("FE%d: IQC read=%d, current=%x", state->fe->id, (u32) state->adc_diff, state->step); 1011 1012 /* first turn for this frequency */ 1013 if (state->step == 0) { 1014 if (state->dc->pga && state->adc_diff < 0) 1015 state->step = 0x10; 1016 if (state->dc->pga == 0 && state->adc_diff > 0) 1017 state->step = 0x10; 1018 } 1019 1020 state->adc_diff = ABS(state->adc_diff); 1021 1022 if (state->adc_diff < state->min_adc_diff && steps(state->step) < 15) { /* stop search when the delta to 0 is increasing */ 1023 state->step++; 1024 state->min_adc_diff = state->adc_diff; 1025 *tune_state = CT_TUNER_STEP_1; 1026 } else { 1027 1028 /* the minimum was what we have seen in the step before */ 1029 state->step--; 1030 dib0090_set_trim(state); 1031 1032 dprintk("FE%d: BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->fe->id, state->dc->addr, state->adc_diff, 1033 state->step); 1034 1035 state->dc++; 1036 if (state->dc->addr == 0) /* done */ 1037 *tune_state = CT_TUNER_STEP_6; 1038 else 1039 *tune_state = CT_TUNER_STEP_0; 1040 1041 } 1042 break; 1043 1044 case CT_TUNER_STEP_6: 1045 dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008); 1046 dib0090_write_reg(state, 0x1f, 0x7); 1047 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ 1048 state->reset &= ~0x1; 1049 default: 1050 break; 1051 } 1052 return ret; 1053} 1054 1055static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state) 1056{ 1057 switch (*tune_state) { 1058 case CT_TUNER_START: 1059 /* WBD-mode=log, Bias=2, Gain=6, Testmode=1, en=1, WBDMUX=1 */ 1060 dib0090_write_reg(state, 0x10, 0xdb09 | (1 << 10)); 1061 dib0090_write_reg(state, 0x24, EN_UHF & 0x0fff); 1062 1063 *tune_state = CT_TUNER_STEP_0; 1064 return 90; /* wait for the WBDMUX to switch and for the ADC to sample */ 1065 case CT_TUNER_STEP_0: 1066 state->wbd_offset = dib0090_read_reg(state, 0x1d); 1067 dprintk("WBD calibration offset = %d", state->wbd_offset); 1068 1069 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ 1070 state->reset &= ~0x2; 1071 break; 1072 default: 1073 break; 1074 } 1075 return 0; 1076} 1077 1078static void dib0090_set_bandwidth(struct dib0090_state *state) 1079{ 1080 u16 tmp; 1081 1082 if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000) 1083 tmp = (3 << 14); 1084 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000) 1085 tmp = (2 << 14); 1086 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000) 1087 tmp = (1 << 14); 1088 else 1089 tmp = (0 << 14); 1090 1091 state->bb_1_def &= 0x3fff; 1092 state->bb_1_def |= tmp; 1093 1094 dib0090_write_reg(state, 0x01, state->bb_1_def); /* be sure that we have the right bb-filter */ 1095} 1096 1097static const struct dib0090_pll dib0090_pll_table[] = { 1098#ifdef CONFIG_BAND_CBAND 1099 {56000, 0, 9, 48, 6}, 1100 {70000, 1, 9, 48, 6}, 1101 {87000, 0, 8, 32, 4}, 1102 {105000, 1, 8, 32, 4}, 1103 {115000, 0, 7, 24, 6}, 1104 {140000, 1, 7, 24, 6}, 1105 {170000, 0, 6, 16, 4}, 1106#endif 1107#ifdef CONFIG_BAND_VHF 1108 {200000, 1, 6, 16, 4}, 1109 {230000, 0, 5, 12, 6}, 1110 {280000, 1, 5, 12, 6}, 1111 {340000, 0, 4, 8, 4}, 1112 {380000, 1, 4, 8, 4}, 1113 {450000, 0, 3, 6, 6}, 1114#endif 1115#ifdef CONFIG_BAND_UHF 1116 {580000, 1, 3, 6, 6}, 1117 {700000, 0, 2, 4, 4}, 1118 {860000, 1, 2, 4, 4}, 1119#endif 1120#ifdef CONFIG_BAND_LBAND 1121 {1800000, 1, 0, 2, 4}, 1122#endif 1123#ifdef CONFIG_BAND_SBAND 1124 {2900000, 0, 14, 1, 4}, 1125#endif 1126}; 1127 1128static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = { 1129 1130#ifdef CONFIG_BAND_CBAND 1131 {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, 1132 {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, 1133 {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, 1134#endif 1135#ifdef CONFIG_BAND_UHF 1136 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1137 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1138 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1139 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1140 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1141 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1142#endif 1143#ifdef CONFIG_BAND_LBAND 1144 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1145 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1146 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1147#endif 1148#ifdef CONFIG_BAND_SBAND 1149 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, 1150 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, 1151#endif 1152}; 1153 1154static const struct dib0090_tuning dib0090_tuning_table[] = { 1155 1156#ifdef CONFIG_BAND_CBAND 1157 {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, 1158#endif 1159#ifdef CONFIG_BAND_VHF 1160 {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, 1161 {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, 1162 {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, 1163#endif 1164#ifdef CONFIG_BAND_UHF 1165 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1166 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1167 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1168 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1169 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1170 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, 1171#endif 1172#ifdef CONFIG_BAND_LBAND 1173 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1174 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1175 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, 1176#endif 1177#ifdef CONFIG_BAND_SBAND 1178 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, 1179 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, 1180#endif 1181}; 1182 1183#define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */ 1184static int dib0090_tune(struct dvb_frontend *fe) 1185{ 1186 struct dib0090_state *state = fe->tuner_priv; 1187 const struct dib0090_tuning *tune = state->current_tune_table_index; 1188 const struct dib0090_pll *pll = state->current_pll_table_index; 1189 enum frontend_tune_state *tune_state = &state->tune_state; 1190 1191 u32 rf; 1192 u16 lo4 = 0xe900, lo5, lo6, Den; 1193 u32 FBDiv, Rest, FREF, VCOF_kHz = 0; 1194 u16 tmp, adc; 1195 int8_t step_sign; 1196 int ret = 10; /* 1ms is the default delay most of the time */ 1197 u8 c, i; 1198 1199 state->current_band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000); 1200 rf = fe->dtv_property_cache.frequency / 1000 + (state->current_band == 1201 BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->freq_offset_khz_vhf); 1202 /* in any case we first need to do a reset if needed */ 1203 if (state->reset & 0x1) 1204 return dib0090_dc_offset_calibration(state, tune_state); 1205 else if (state->reset & 0x2) 1206 return dib0090_wbd_calibration(state, tune_state); 1207 1208 /************************* VCO ***************************/ 1209 /* Default values for FG */ 1210 /* from these are needed : */ 1211 /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv */ 1212 1213#ifdef CONFIG_SYS_ISDBT 1214 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1) 1215 rf += 850; 1216#endif 1217 1218 if (state->current_rf != rf) { 1219 state->tuner_is_tuned = 0; 1220 1221 tune = dib0090_tuning_table; 1222 1223 tmp = (state->revision >> 5) & 0x7; 1224 if (tmp == 0x4 || tmp == 0x7) { 1225 /* CBAND tuner version for VHF */ 1226 if (state->current_band == BAND_FM || state->current_band == BAND_VHF) { 1227 /* Force CBAND */ 1228 state->current_band = BAND_CBAND; 1229 tune = dib0090_tuning_table_fm_vhf_on_cband; 1230 } 1231 } 1232 1233 pll = dib0090_pll_table; 1234 /* Look for the interval */ 1235 while (rf > tune->max_freq) 1236 tune++; 1237 while (rf > pll->max_freq) 1238 pll++; 1239 state->current_tune_table_index = tune; 1240 state->current_pll_table_index = pll; 1241 } 1242 1243 if (*tune_state == CT_TUNER_START) { 1244 1245 if (state->tuner_is_tuned == 0) 1246 state->current_rf = 0; 1247 1248 if (state->current_rf != rf) { 1249 1250 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim)); 1251 1252 /* external loop filter, otherwise: 1253 * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4; 1254 * lo6 = 0x0e34 */ 1255 if (pll->vco_band) 1256 lo5 = 0x049e; 1257 else if (state->config->analog_output) 1258 lo5 = 0x041d; 1259 else 1260 lo5 = 0x041c; 1261 1262 lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7); /* bit 15 is the split to the slave, we do not do it here */ 1263 1264 if (!state->config->io.pll_int_loop_filt) 1265 lo6 = 0xff28; 1266 else 1267 lo6 = (state->config->io.pll_int_loop_filt << 3); 1268 1269 VCOF_kHz = (pll->hfdiv * rf) * 2; 1270 1271 FREF = state->config->io.clock_khz; 1272 1273 FBDiv = (VCOF_kHz / pll->topresc / FREF); 1274 Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF; 1275 1276 if (Rest < LPF) 1277 Rest = 0; 1278 else if (Rest < 2 * LPF) 1279 Rest = 2 * LPF; 1280 else if (Rest > (FREF - LPF)) { 1281 Rest = 0; 1282 FBDiv += 1; 1283 } else if (Rest > (FREF - 2 * LPF)) 1284 Rest = FREF - 2 * LPF; 1285 Rest = (Rest * 6528) / (FREF / 10); 1286 1287 Den = 1; 1288 1289 dprintk(" ***** ******* Rest value = %d", Rest); 1290 1291 if (Rest > 0) { 1292 if (state->config->analog_output) 1293 lo6 |= (1 << 2) | 2; 1294 else 1295 lo6 |= (1 << 2) | 1; 1296 Den = 255; 1297 } 1298#ifdef CONFIG_BAND_SBAND 1299 if (state->current_band == BAND_SBAND) 1300 lo6 &= 0xfffb; 1301#endif 1302 1303 dib0090_write_reg(state, 0x15, (u16) FBDiv); 1304 1305 dib0090_write_reg(state, 0x16, (Den << 8) | 1); 1306 1307 dib0090_write_reg(state, 0x17, (u16) Rest); 1308 1309 dib0090_write_reg(state, 0x19, lo5); 1310 1311 dib0090_write_reg(state, 0x1c, lo6); 1312 1313 lo6 = tune->tuner_enable; 1314 if (state->config->analog_output) 1315 lo6 = (lo6 & 0xff9f) | 0x2; 1316 1317 dib0090_write_reg(state, 0x24, lo6 | EN_LO 1318#ifdef CONFIG_DIB0090_USE_PWM_AGC 1319 | state->config->use_pwm_agc * EN_CRYSTAL 1320#endif 1321 ); 1322 1323 state->current_rf = rf; 1324 1325 /* prepare a complete captrim */ 1326 state->step = state->captrim = state->fcaptrim = 64; 1327 1328 } else { /* we are already tuned to this frequency - the configuration is correct */ 1329 1330 /* do a minimal captrim even if the frequency has not changed */ 1331 state->step = 4; 1332 state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f; 1333 } 1334 state->adc_diff = 3000; 1335 1336 dib0090_write_reg(state, 0x10, 0x2B1); 1337 1338 dib0090_write_reg(state, 0x1e, 0x0032); 1339 1340 ret = 20; 1341 *tune_state = CT_TUNER_STEP_1; 1342 } else if (*tune_state == CT_TUNER_STEP_0) { 1343 /* nothing */ 1344 } else if (*tune_state == CT_TUNER_STEP_1) { 1345 state->step /= 2; 1346 dib0090_write_reg(state, 0x18, lo4 | state->captrim); 1347 *tune_state = CT_TUNER_STEP_2; 1348 } else if (*tune_state == CT_TUNER_STEP_2) { 1349 1350 adc = dib0090_read_reg(state, 0x1d); 1351 dprintk("FE %d CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) fe->id, (u32) state->captrim, (u32) adc, 1352 (u32) (adc) * (u32) 1800 / (u32) 1024); 1353 1354 if (adc >= 400) { 1355 adc -= 400; 1356 step_sign = -1; 1357 } else { 1358 adc = 400 - adc; 1359 step_sign = 1; 1360 } 1361 1362 if (adc < state->adc_diff) { 1363 dprintk("FE %d CAPTRIM=%d is closer to target (%d/%d)", (u32) fe->id, (u32) state->captrim, (u32) adc, (u32) state->adc_diff); 1364 state->adc_diff = adc; 1365 state->fcaptrim = state->captrim; 1366 1367 } 1368 1369 state->captrim += step_sign * state->step; 1370 if (state->step >= 1) 1371 *tune_state = CT_TUNER_STEP_1; 1372 else 1373 *tune_state = CT_TUNER_STEP_3; 1374 1375 ret = 15; 1376 } else if (*tune_state == CT_TUNER_STEP_3) { 1377 /*write the final cptrim config */ 1378 dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim); 1379 1380#ifdef CONFIG_TUNER_DIB0090_CAPTRIM_MEMORY 1381 state->memory[state->memory_index].cap = state->fcaptrim; 1382#endif 1383 1384 *tune_state = CT_TUNER_STEP_4; 1385 } else if (*tune_state == CT_TUNER_STEP_4) { 1386 dib0090_write_reg(state, 0x1e, 0x07ff); 1387 1388 dprintk("FE %d Final Captrim: %d", (u32) fe->id, (u32) state->fcaptrim); 1389 dprintk("FE %d HFDIV code: %d", (u32) fe->id, (u32) pll->hfdiv_code); 1390 dprintk("FE %d VCO = %d", (u32) fe->id, (u32) pll->vco_band); 1391 dprintk("FE %d VCOF in kHz: %d ((%d*%d) << 1))", (u32) fe->id, (u32) ((pll->hfdiv * rf) * 2), (u32) pll->hfdiv, (u32) rf); 1392 dprintk("FE %d REFDIV: %d, FREF: %d", (u32) fe->id, (u32) 1, (u32) state->config->io.clock_khz); 1393 dprintk("FE %d FBDIV: %d, Rest: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17)); 1394 dprintk("FE %d Num: %d, Den: %d, SD: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x17), 1395 (u32) (dib0090_read_reg(state, 0x16) >> 8), (u32) dib0090_read_reg(state, 0x1c) & 0x3); 1396 1397 c = 4; 1398 i = 3; 1399#if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND) 1400 if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND)) { 1401 c = 2; 1402 i = 2; 1403 } 1404#endif 1405 dib0090_write_reg(state, 0x10, (c << 13) | (i << 11) | (WBD 1406#ifdef CONFIG_DIB0090_USE_PWM_AGC 1407 | (state->config->use_pwm_agc << 1) 1408#endif 1409 )); 1410 dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | (tune->lna_bias << 0)); 1411 dib0090_write_reg(state, 0x0c, tune->v2i); 1412 dib0090_write_reg(state, 0x0d, tune->mix); 1413 dib0090_write_reg(state, 0x0e, tune->load); 1414 1415 *tune_state = CT_TUNER_STEP_5; 1416 } else if (*tune_state == CT_TUNER_STEP_5) { 1417 1418 /* initialize the lt gain register */ 1419 state->rf_lt_def = 0x7c00; 1420 dib0090_write_reg(state, 0x0f, state->rf_lt_def); 1421 1422 dib0090_set_bandwidth(state); 1423 state->tuner_is_tuned = 1; 1424 *tune_state = CT_TUNER_STOP; 1425 } else 1426 ret = FE_CALLBACK_TIME_NEVER; 1427 return ret; 1428} 1429 1430static int dib0090_release(struct dvb_frontend *fe) 1431{ 1432 kfree(fe->tuner_priv); 1433 fe->tuner_priv = NULL; 1434 return 0; 1435} 1436 1437enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe) 1438{ 1439 struct dib0090_state *state = fe->tuner_priv; 1440 1441 return state->tune_state; 1442} 1443EXPORT_SYMBOL(dib0090_get_tune_state); 1444 1445int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) 1446{ 1447 struct dib0090_state *state = fe->tuner_priv; 1448 1449 state->tune_state = tune_state; 1450 return 0; 1451} 1452EXPORT_SYMBOL(dib0090_set_tune_state); 1453 1454static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency) 1455{ 1456 struct dib0090_state *state = fe->tuner_priv; 1457 1458 *frequency = 1000 * state->current_rf; 1459 return 0; 1460} 1461 1462static int dib0090_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) 1463{ 1464 struct dib0090_state *state = fe->tuner_priv; 1465 uint32_t ret; 1466 1467 state->tune_state = CT_TUNER_START; 1468 1469 do { 1470 ret = dib0090_tune(fe); 1471 if (ret != FE_CALLBACK_TIME_NEVER) 1472 msleep(ret / 10); 1473 else 1474 break; 1475 } while (state->tune_state != CT_TUNER_STOP); 1476 1477 return 0; 1478} 1479 1480static const struct dvb_tuner_ops dib0090_ops = { 1481 .info = { 1482 .name = "DiBcom DiB0090", 1483 .frequency_min = 45000000, 1484 .frequency_max = 860000000, 1485 .frequency_step = 1000, 1486 }, 1487 .release = dib0090_release, 1488 1489 .init = dib0090_wakeup, 1490 .sleep = dib0090_sleep, 1491 .set_params = dib0090_set_params, 1492 .get_frequency = dib0090_get_frequency, 1493}; 1494 1495struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) 1496{ 1497 struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL); 1498 if (st == NULL) 1499 return NULL; 1500 1501 st->config = config; 1502 st->i2c = i2c; 1503 st->fe = fe; 1504 fe->tuner_priv = st; 1505 1506 if (dib0090_reset(fe) != 0) 1507 goto free_mem; 1508 1509 printk(KERN_INFO "DiB0090: successfully identified\n"); 1510 memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops)); 1511 1512 return fe; 1513 free_mem: 1514 kfree(st); 1515 fe->tuner_priv = NULL; 1516 return NULL; 1517} 1518EXPORT_SYMBOL(dib0090_register); 1519 1520MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); 1521MODULE_AUTHOR("Olivier Grenie <olivier.grenie@dibcom.fr>"); 1522MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner"); 1523MODULE_LICENSE("GPL"); 1524