0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0012
0013 #include <linux/kernel.h>
0014 #include <linux/slab.h>
0015 #include <linux/i2c.h>
0016 #include <linux/mutex.h>
0017
0018 #include <media/dvb_frontend.h>
0019
0020 #include "dib0090.h"
0021 #include "dibx000_common.h"
0022
0023 static int debug;
0024 module_param(debug, int, 0644);
0025 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
0026
0027 #define dprintk(fmt, arg...) do { \
0028 if (debug) \
0029 printk(KERN_DEBUG pr_fmt("%s: " fmt), \
0030 __func__, ##arg); \
0031 } while (0)
0032
0033 #define CONFIG_SYS_DVBT
0034 #define CONFIG_SYS_ISDBT
0035 #define CONFIG_BAND_CBAND
0036 #define CONFIG_BAND_VHF
0037 #define CONFIG_BAND_UHF
0038 #define CONFIG_DIB0090_USE_PWM_AGC
0039
0040 #define EN_LNA0 0x8000
0041 #define EN_LNA1 0x4000
0042 #define EN_LNA2 0x2000
0043 #define EN_LNA3 0x1000
0044 #define EN_MIX0 0x0800
0045 #define EN_MIX1 0x0400
0046 #define EN_MIX2 0x0200
0047 #define EN_MIX3 0x0100
0048 #define EN_IQADC 0x0040
0049 #define EN_PLL 0x0020
0050 #define EN_TX 0x0010
0051 #define EN_BB 0x0008
0052 #define EN_LO 0x0004
0053 #define EN_BIAS 0x0001
0054
0055 #define EN_IQANA 0x0002
0056 #define EN_DIGCLK 0x0080
0057 #define EN_CRYSTAL 0x0002
0058
0059 #define EN_UHF 0x22E9
0060 #define EN_VHF 0x44E9
0061 #define EN_LBD 0x11E9
0062 #define EN_SBD 0x44E9
0063 #define EN_CAB 0x88E9
0064
0065
0066 #define DC_CAL 0x1
0067 #define WBD_CAL 0x2
0068 #define TEMP_CAL 0x4
0069 #define CAPTRIM_CAL 0x8
0070
0071 #define KROSUS_PLL_LOCKED 0x800
0072 #define KROSUS 0x2
0073
0074
0075 #define SOC 0x02
0076 #define SOC_7090_P1G_11R1 0x82
0077 #define SOC_7090_P1G_21R1 0x8a
0078 #define SOC_8090_P1G_11R1 0x86
0079 #define SOC_8090_P1G_21R1 0x8e
0080
0081
0082 #define P1A_B 0x0
0083 #define P1C 0x1
0084 #define P1D_E_F 0x3
0085 #define P1G 0x7
0086 #define P1G_21R2 0xf
0087
0088 #define MP001 0x1
0089 #define MP005 0x4
0090 #define MP008 0x6
0091 #define MP009 0x7
0092
0093 #define pgm_read_word(w) (*w)
0094
0095 struct dc_calibration;
0096
0097 struct dib0090_tuning {
0098 u32 max_freq;
0099 u8 switch_trim;
0100 u8 lna_tune;
0101 u16 lna_bias;
0102 u16 v2i;
0103 u16 mix;
0104 u16 load;
0105 u16 tuner_enable;
0106 };
0107
0108 struct dib0090_pll {
0109 u32 max_freq;
0110 u8 vco_band;
0111 u8 hfdiv_code;
0112 u8 hfdiv;
0113 u8 topresc;
0114 };
0115
0116 struct dib0090_identity {
0117 u8 version;
0118 u8 product;
0119 u8 p1g;
0120 u8 in_soc;
0121 };
0122
0123 struct dib0090_state {
0124 struct i2c_adapter *i2c;
0125 struct dvb_frontend *fe;
0126 const struct dib0090_config *config;
0127
0128 u8 current_band;
0129 enum frontend_tune_state tune_state;
0130 u32 current_rf;
0131
0132 u16 wbd_offset;
0133 s16 wbd_target;
0134
0135 s16 rf_gain_limit;
0136 s16 current_gain;
0137 u8 agc_step;
0138
0139 u16 gain[2];
0140
0141 const u16 *rf_ramp;
0142 const u16 *bb_ramp;
0143
0144
0145 u16 bb_1_def;
0146 u16 rf_lt_def;
0147 u16 gain_reg[4];
0148
0149
0150 s8 step;
0151 s16 adc_diff;
0152 s16 min_adc_diff;
0153
0154 s8 captrim;
0155 s8 fcaptrim;
0156
0157 const struct dc_calibration *dc;
0158 u16 bb6, bb7;
0159
0160 const struct dib0090_tuning *current_tune_table_index;
0161 const struct dib0090_pll *current_pll_table_index;
0162
0163 u8 tuner_is_tuned;
0164 u8 agc_freeze;
0165
0166 struct dib0090_identity identity;
0167
0168 u32 rf_request;
0169 u8 current_standard;
0170
0171 u8 calibrate;
0172 u32 rest;
0173 u16 bias;
0174 s16 temperature;
0175
0176 u8 wbd_calibration_gain;
0177 const struct dib0090_wbd_slope *current_wbd_table;
0178 u16 wbdmux;
0179
0180
0181 struct i2c_msg msg[2];
0182 u8 i2c_write_buffer[3];
0183 u8 i2c_read_buffer[2];
0184 struct mutex i2c_buffer_lock;
0185 };
0186
0187 struct dib0090_fw_state {
0188 struct i2c_adapter *i2c;
0189 struct dvb_frontend *fe;
0190 struct dib0090_identity identity;
0191 const struct dib0090_config *config;
0192
0193
0194 struct i2c_msg msg;
0195 u8 i2c_write_buffer[2];
0196 u8 i2c_read_buffer[2];
0197 struct mutex i2c_buffer_lock;
0198 };
0199
0200 static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
0201 {
0202 u16 ret;
0203
0204 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
0205 dprintk("could not acquire lock\n");
0206 return 0;
0207 }
0208
0209 state->i2c_write_buffer[0] = reg;
0210
0211 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
0212 state->msg[0].addr = state->config->i2c_address;
0213 state->msg[0].flags = 0;
0214 state->msg[0].buf = state->i2c_write_buffer;
0215 state->msg[0].len = 1;
0216 state->msg[1].addr = state->config->i2c_address;
0217 state->msg[1].flags = I2C_M_RD;
0218 state->msg[1].buf = state->i2c_read_buffer;
0219 state->msg[1].len = 2;
0220
0221 if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
0222 pr_warn("DiB0090 I2C read failed\n");
0223 ret = 0;
0224 } else
0225 ret = (state->i2c_read_buffer[0] << 8)
0226 | state->i2c_read_buffer[1];
0227
0228 mutex_unlock(&state->i2c_buffer_lock);
0229 return ret;
0230 }
0231
0232 static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
0233 {
0234 int ret;
0235
0236 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
0237 dprintk("could not acquire lock\n");
0238 return -EINVAL;
0239 }
0240
0241 state->i2c_write_buffer[0] = reg & 0xff;
0242 state->i2c_write_buffer[1] = val >> 8;
0243 state->i2c_write_buffer[2] = val & 0xff;
0244
0245 memset(state->msg, 0, sizeof(struct i2c_msg));
0246 state->msg[0].addr = state->config->i2c_address;
0247 state->msg[0].flags = 0;
0248 state->msg[0].buf = state->i2c_write_buffer;
0249 state->msg[0].len = 3;
0250
0251 if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
0252 pr_warn("DiB0090 I2C write failed\n");
0253 ret = -EREMOTEIO;
0254 } else
0255 ret = 0;
0256
0257 mutex_unlock(&state->i2c_buffer_lock);
0258 return ret;
0259 }
0260
0261 static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
0262 {
0263 u16 ret;
0264
0265 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
0266 dprintk("could not acquire lock\n");
0267 return 0;
0268 }
0269
0270 state->i2c_write_buffer[0] = reg;
0271
0272 memset(&state->msg, 0, sizeof(struct i2c_msg));
0273 state->msg.addr = reg;
0274 state->msg.flags = I2C_M_RD;
0275 state->msg.buf = state->i2c_read_buffer;
0276 state->msg.len = 2;
0277 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
0278 pr_warn("DiB0090 I2C read failed\n");
0279 ret = 0;
0280 } else
0281 ret = (state->i2c_read_buffer[0] << 8)
0282 | state->i2c_read_buffer[1];
0283
0284 mutex_unlock(&state->i2c_buffer_lock);
0285 return ret;
0286 }
0287
0288 static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
0289 {
0290 int ret;
0291
0292 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
0293 dprintk("could not acquire lock\n");
0294 return -EINVAL;
0295 }
0296
0297 state->i2c_write_buffer[0] = val >> 8;
0298 state->i2c_write_buffer[1] = val & 0xff;
0299
0300 memset(&state->msg, 0, sizeof(struct i2c_msg));
0301 state->msg.addr = reg;
0302 state->msg.flags = 0;
0303 state->msg.buf = state->i2c_write_buffer;
0304 state->msg.len = 2;
0305 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
0306 pr_warn("DiB0090 I2C write failed\n");
0307 ret = -EREMOTEIO;
0308 } else
0309 ret = 0;
0310
0311 mutex_unlock(&state->i2c_buffer_lock);
0312 return ret;
0313 }
0314
0315 #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)
0316 #define ADC_TARGET -220
0317 #define GAIN_ALPHA 5
0318 #define WBD_ALPHA 6
0319 #define LPF 100
0320 static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c)
0321 {
0322 do {
0323 dib0090_write_reg(state, r++, *b++);
0324 } while (--c);
0325 }
0326
0327 static int dib0090_identify(struct dvb_frontend *fe)
0328 {
0329 struct dib0090_state *state = fe->tuner_priv;
0330 u16 v;
0331 struct dib0090_identity *identity = &state->identity;
0332
0333 v = dib0090_read_reg(state, 0x1a);
0334
0335 identity->p1g = 0;
0336 identity->in_soc = 0;
0337
0338 dprintk("Tuner identification (Version = 0x%04x)\n", v);
0339
0340
0341 v &= ~KROSUS_PLL_LOCKED;
0342
0343 identity->version = v & 0xff;
0344 identity->product = (v >> 8) & 0xf;
0345
0346 if (identity->product != KROSUS)
0347 goto identification_error;
0348
0349 if ((identity->version & 0x3) == SOC) {
0350 identity->in_soc = 1;
0351 switch (identity->version) {
0352 case SOC_8090_P1G_11R1:
0353 dprintk("SOC 8090 P1-G11R1 Has been detected\n");
0354 identity->p1g = 1;
0355 break;
0356 case SOC_8090_P1G_21R1:
0357 dprintk("SOC 8090 P1-G21R1 Has been detected\n");
0358 identity->p1g = 1;
0359 break;
0360 case SOC_7090_P1G_11R1:
0361 dprintk("SOC 7090 P1-G11R1 Has been detected\n");
0362 identity->p1g = 1;
0363 break;
0364 case SOC_7090_P1G_21R1:
0365 dprintk("SOC 7090 P1-G21R1 Has been detected\n");
0366 identity->p1g = 1;
0367 break;
0368 default:
0369 goto identification_error;
0370 }
0371 } else {
0372 switch ((identity->version >> 5) & 0x7) {
0373 case MP001:
0374 dprintk("MP001 : 9090/8096\n");
0375 break;
0376 case MP005:
0377 dprintk("MP005 : Single Sband\n");
0378 break;
0379 case MP008:
0380 dprintk("MP008 : diversity VHF-UHF-LBAND\n");
0381 break;
0382 case MP009:
0383 dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND\n");
0384 break;
0385 default:
0386 goto identification_error;
0387 }
0388
0389 switch (identity->version & 0x1f) {
0390 case P1G_21R2:
0391 dprintk("P1G_21R2 detected\n");
0392 identity->p1g = 1;
0393 break;
0394 case P1G:
0395 dprintk("P1G detected\n");
0396 identity->p1g = 1;
0397 break;
0398 case P1D_E_F:
0399 dprintk("P1D/E/F detected\n");
0400 break;
0401 case P1C:
0402 dprintk("P1C detected\n");
0403 break;
0404 case P1A_B:
0405 dprintk("P1-A/B detected: driver is deactivated - not available\n");
0406 goto identification_error;
0407 break;
0408 default:
0409 goto identification_error;
0410 }
0411 }
0412
0413 return 0;
0414
0415 identification_error:
0416 return -EIO;
0417 }
0418
0419 static int dib0090_fw_identify(struct dvb_frontend *fe)
0420 {
0421 struct dib0090_fw_state *state = fe->tuner_priv;
0422 struct dib0090_identity *identity = &state->identity;
0423
0424 u16 v = dib0090_fw_read_reg(state, 0x1a);
0425 identity->p1g = 0;
0426 identity->in_soc = 0;
0427
0428 dprintk("FE: Tuner identification (Version = 0x%04x)\n", v);
0429
0430
0431 v &= ~KROSUS_PLL_LOCKED;
0432
0433 identity->version = v & 0xff;
0434 identity->product = (v >> 8) & 0xf;
0435
0436 if (identity->product != KROSUS)
0437 goto identification_error;
0438
0439 if ((identity->version & 0x3) == SOC) {
0440 identity->in_soc = 1;
0441 switch (identity->version) {
0442 case SOC_8090_P1G_11R1:
0443 dprintk("SOC 8090 P1-G11R1 Has been detected\n");
0444 identity->p1g = 1;
0445 break;
0446 case SOC_8090_P1G_21R1:
0447 dprintk("SOC 8090 P1-G21R1 Has been detected\n");
0448 identity->p1g = 1;
0449 break;
0450 case SOC_7090_P1G_11R1:
0451 dprintk("SOC 7090 P1-G11R1 Has been detected\n");
0452 identity->p1g = 1;
0453 break;
0454 case SOC_7090_P1G_21R1:
0455 dprintk("SOC 7090 P1-G21R1 Has been detected\n");
0456 identity->p1g = 1;
0457 break;
0458 default:
0459 goto identification_error;
0460 }
0461 } else {
0462 switch ((identity->version >> 5) & 0x7) {
0463 case MP001:
0464 dprintk("MP001 : 9090/8096\n");
0465 break;
0466 case MP005:
0467 dprintk("MP005 : Single Sband\n");
0468 break;
0469 case MP008:
0470 dprintk("MP008 : diversity VHF-UHF-LBAND\n");
0471 break;
0472 case MP009:
0473 dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND\n");
0474 break;
0475 default:
0476 goto identification_error;
0477 }
0478
0479 switch (identity->version & 0x1f) {
0480 case P1G_21R2:
0481 dprintk("P1G_21R2 detected\n");
0482 identity->p1g = 1;
0483 break;
0484 case P1G:
0485 dprintk("P1G detected\n");
0486 identity->p1g = 1;
0487 break;
0488 case P1D_E_F:
0489 dprintk("P1D/E/F detected\n");
0490 break;
0491 case P1C:
0492 dprintk("P1C detected\n");
0493 break;
0494 case P1A_B:
0495 dprintk("P1-A/B detected: driver is deactivated - not available\n");
0496 goto identification_error;
0497 break;
0498 default:
0499 goto identification_error;
0500 }
0501 }
0502
0503 return 0;
0504
0505 identification_error:
0506 return -EIO;
0507 }
0508
0509 static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
0510 {
0511 struct dib0090_state *state = fe->tuner_priv;
0512 u16 PllCfg, i, v;
0513
0514 HARD_RESET(state);
0515 dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
0516 if (cfg->in_soc)
0517 return;
0518
0519 dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);
0520
0521 dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
0522 if (cfg->clkoutdrive != 0)
0523 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
0524 | (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
0525 else
0526 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
0527 | (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
0528
0529
0530 PllCfg = dib0090_read_reg(state, 0x21);
0531
0532
0533 if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && (!cfg->in_soc)
0534 && !cfg->io.pll_bypass) {
0535
0536
0537 PllCfg |= (1 << 15);
0538 dib0090_write_reg(state, 0x21, PllCfg);
0539
0540
0541 PllCfg &= ~(1 << 13);
0542 dib0090_write_reg(state, 0x21, PllCfg);
0543
0544
0545 PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
0546 dib0090_write_reg(state, 0x21, PllCfg);
0547
0548
0549 PllCfg |= (1 << 13);
0550 dib0090_write_reg(state, 0x21, PllCfg);
0551
0552
0553 i = 100;
0554 do {
0555 v = !!(dib0090_read_reg(state, 0x1a) & 0x800);
0556 if (v)
0557 break;
0558 } while (--i);
0559
0560 if (i == 0) {
0561 dprintk("Pll: Unable to lock Pll\n");
0562 return;
0563 }
0564
0565
0566 PllCfg &= ~(1 << 15);
0567 dib0090_write_reg(state, 0x21, PllCfg);
0568 }
0569
0570 if (cfg->io.pll_bypass) {
0571 PllCfg |= (cfg->io.pll_bypass << 15);
0572 dib0090_write_reg(state, 0x21, PllCfg);
0573 }
0574 }
0575
0576 static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
0577 {
0578 struct dib0090_fw_state *state = fe->tuner_priv;
0579 u16 PllCfg;
0580 u16 v;
0581 int i;
0582
0583 dprintk("fw reset digital\n");
0584 HARD_RESET(state);
0585
0586 dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
0587 dib0090_fw_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);
0588
0589 dib0090_fw_write_reg(state, 0x20,
0590 ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (cfg->data_tx_drv << 4) | cfg->ls_cfg_pad_drv);
0591
0592 v = (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 9) | (0 << 8) | (cfg->clkouttobamse << 4) | (0 << 2) | (0);
0593 if (cfg->clkoutdrive != 0)
0594 v |= cfg->clkoutdrive << 5;
0595 else
0596 v |= 7 << 5;
0597
0598 v |= 2 << 10;
0599 dib0090_fw_write_reg(state, 0x23, v);
0600
0601
0602 PllCfg = dib0090_fw_read_reg(state, 0x21);
0603
0604
0605 if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && !cfg->io.pll_bypass) {
0606
0607
0608 PllCfg |= (1 << 15);
0609 dib0090_fw_write_reg(state, 0x21, PllCfg);
0610
0611
0612 PllCfg &= ~(1 << 13);
0613 dib0090_fw_write_reg(state, 0x21, PllCfg);
0614
0615
0616 PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
0617 dib0090_fw_write_reg(state, 0x21, PllCfg);
0618
0619
0620 PllCfg |= (1 << 13);
0621 dib0090_fw_write_reg(state, 0x21, PllCfg);
0622
0623
0624 i = 100;
0625 do {
0626 v = !!(dib0090_fw_read_reg(state, 0x1a) & 0x800);
0627 if (v)
0628 break;
0629 } while (--i);
0630
0631 if (i == 0) {
0632 dprintk("Pll: Unable to lock Pll\n");
0633 return -EIO;
0634 }
0635
0636
0637 PllCfg &= ~(1 << 15);
0638 dib0090_fw_write_reg(state, 0x21, PllCfg);
0639 }
0640
0641 if (cfg->io.pll_bypass) {
0642 PllCfg |= (cfg->io.pll_bypass << 15);
0643 dib0090_fw_write_reg(state, 0x21, PllCfg);
0644 }
0645
0646 return dib0090_fw_identify(fe);
0647 }
0648
0649 static int dib0090_wakeup(struct dvb_frontend *fe)
0650 {
0651 struct dib0090_state *state = fe->tuner_priv;
0652 if (state->config->sleep)
0653 state->config->sleep(fe, 0);
0654
0655
0656 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
0657 return 0;
0658 }
0659
0660 static int dib0090_sleep(struct dvb_frontend *fe)
0661 {
0662 struct dib0090_state *state = fe->tuner_priv;
0663 if (state->config->sleep)
0664 state->config->sleep(fe, 1);
0665 return 0;
0666 }
0667
0668 void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
0669 {
0670 struct dib0090_state *state = fe->tuner_priv;
0671 if (fast)
0672 dib0090_write_reg(state, 0x04, 0);
0673 else
0674 dib0090_write_reg(state, 0x04, 1);
0675 }
0676
0677 EXPORT_SYMBOL(dib0090_dcc_freq);
0678
0679 static const u16 bb_ramp_pwm_normal_socs[] = {
0680 550,
0681 (1<<9) | 8,
0682 440,
0683 (4 << 9) | 0,
0684 (0 << 9) | 208,
0685 (4 << 9) | 208,
0686 (0 << 9) | 440,
0687 };
0688
0689 static const u16 rf_ramp_pwm_cband_7090p[] = {
0690 280,
0691 18,
0692 504,
0693 (29 << 10) | 364,
0694 (0 << 10) | 504,
0695 (60 << 10) | 228,
0696 (0 << 10) | 364,
0697 (34 << 10) | 109,
0698 (0 << 10) | 228,
0699 (37 << 10) | 0,
0700 (0 << 10) | 109,
0701 };
0702
0703 static const u16 rf_ramp_pwm_cband_7090e_sensitivity[] = {
0704 186,
0705 40,
0706 746,
0707 (10 << 10) | 345,
0708 (0 << 10) | 746,
0709 (0 << 10) | 0,
0710 (0 << 10) | 0,
0711 (28 << 10) | 200,
0712 (0 << 10) | 345,
0713 (20 << 10) | 0,
0714 (0 << 10) | 200,
0715 };
0716
0717 static const u16 rf_ramp_pwm_cband_7090e_aci[] = {
0718 86,
0719 40,
0720 345,
0721 (0 << 10) | 0,
0722 (0 << 10) | 0,
0723 (0 << 10) | 0,
0724 (0 << 10) | 0,
0725 (28 << 10) | 200,
0726 (0 << 10) | 345,
0727 (20 << 10) | 0,
0728 (0 << 10) | 200,
0729 };
0730
0731 static const u16 rf_ramp_pwm_cband_8090[] = {
0732 345,
0733 29,
0734 1000,
0735 (35 << 10) | 772,
0736 (0 << 10) | 1000,
0737 (58 << 10) | 496,
0738 (0 << 10) | 772,
0739 (27 << 10) | 200,
0740 (0 << 10) | 496,
0741 (40 << 10) | 0,
0742 (0 << 10) | 200,
0743 };
0744
0745 static const u16 rf_ramp_pwm_uhf_7090[] = {
0746 407,
0747 13,
0748 529,
0749 (23 << 10) | 0,
0750 (0 << 10) | 176,
0751 (63 << 10) | 400,
0752 (0 << 10) | 529,
0753 (48 << 10) | 316,
0754 (0 << 10) | 400,
0755 (29 << 10) | 176,
0756 (0 << 10) | 316,
0757 };
0758
0759 static const u16 rf_ramp_pwm_uhf_8090[] = {
0760 388,
0761 26,
0762 1008,
0763 (11 << 10) | 0,
0764 (0 << 10) | 369,
0765 (41 << 10) | 809,
0766 (0 << 10) | 1008,
0767 (27 << 10) | 659,
0768 (0 << 10) | 809,
0769 (14 << 10) | 369,
0770 (0 << 10) | 659,
0771 };
0772
0773
0774 static const u16 bb_ramp_pwm_normal[] = {
0775 500,
0776 8,
0777 400,
0778 (2 << 9) | 0,
0779 (0 << 9) | 168,
0780 (2 << 9) | 168,
0781 (0 << 9) | 400,
0782 };
0783
0784 #if 0
0785
0786 static const u16 bb_ramp_pwm_boost[] = {
0787 550,
0788 8,
0789 440,
0790 (2 << 9) | 0,
0791 (0 << 9) | 208,
0792 (2 << 9) | 208,
0793 (0 << 9) | 440,
0794 };
0795 #endif
0796
0797 static const u16 rf_ramp_pwm_cband[] = {
0798 314,
0799 33,
0800 1023,
0801 (8 << 10) | 743,
0802 (0 << 10) | 1023,
0803 (15 << 10) | 469,
0804 (0 << 10) | 742,
0805 (9 << 10) | 234,
0806 (0 << 10) | 468,
0807 (9 << 10) | 0,
0808 (0 << 10) | 233,
0809 };
0810
0811 static const u16 rf_ramp_pwm_vhf[] = {
0812 398,
0813 24,
0814 954,
0815 (7 << 10) | 0,
0816 (0 << 10) | 290,
0817 (16 << 10) | 699,
0818 (0 << 10) | 954,
0819 (17 << 10) | 580,
0820 (0 << 10) | 699,
0821 (7 << 10) | 290,
0822 (0 << 10) | 580,
0823 };
0824
0825 static const u16 rf_ramp_pwm_uhf[] = {
0826 398,
0827 24,
0828 954,
0829 (7 << 10) | 0,
0830 (0 << 10) | 290,
0831 (16 << 10) | 699,
0832 (0 << 10) | 954,
0833 (17 << 10) | 580,
0834 (0 << 10) | 699,
0835 (7 << 10) | 290,
0836 (0 << 10) | 580,
0837 };
0838
0839 #if 0
0840
0841 static const u16 rf_ramp_pwm_sband[] = {
0842 253,
0843 38,
0844 961,
0845 (4 << 10) | 0,
0846 (0 << 10) | 508,
0847 (9 << 10) | 508,
0848 (0 << 10) | 961,
0849 (0 << 10) | 0,
0850 (0 << 10) | 0,
0851 (0 << 10) | 0,
0852 (0 << 10) | 0,
0853 };
0854 #endif
0855
0856 struct slope {
0857 s16 range;
0858 s16 slope;
0859 };
0860 static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
0861 {
0862 u8 i;
0863 u16 rest;
0864 u16 ret = 0;
0865 for (i = 0; i < num; i++) {
0866 if (val > slopes[i].range)
0867 rest = slopes[i].range;
0868 else
0869 rest = val;
0870 ret += (rest * slopes[i].slope) / slopes[i].range;
0871 val -= rest;
0872 }
0873 return ret;
0874 }
0875
0876 static const struct slope dib0090_wbd_slopes[3] = {
0877 {66, 120},
0878 {600, 170},
0879 {170, 250},
0880 };
0881
0882 static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
0883 {
0884 wbd &= 0x3ff;
0885 if (wbd < state->wbd_offset)
0886 wbd = 0;
0887 else
0888 wbd -= state->wbd_offset;
0889
0890 return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd);
0891 }
0892
0893 static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
0894 {
0895 u16 offset = 250;
0896
0897
0898
0899 if (state->current_band == BAND_VHF)
0900 offset = 650;
0901 #ifndef FIRMWARE_FIREFLY
0902 if (state->current_band == BAND_VHF)
0903 offset = state->config->wbd_vhf_offset;
0904 if (state->current_band == BAND_CBAND)
0905 offset = state->config->wbd_cband_offset;
0906 #endif
0907
0908 state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
0909 dprintk("wbd-target: %d dB\n", (u32) state->wbd_target);
0910 }
0911
0912 static const int gain_reg_addr[4] = {
0913 0x08, 0x0a, 0x0f, 0x01
0914 };
0915
0916 static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
0917 {
0918 u16 rf, bb, ref;
0919 u16 i, v, gain_reg[4] = { 0 }, gain;
0920 const u16 *g;
0921
0922 if (top_delta < -511)
0923 top_delta = -511;
0924 if (top_delta > 511)
0925 top_delta = 511;
0926
0927 if (force) {
0928 top_delta *= (1 << WBD_ALPHA);
0929 gain_delta *= (1 << GAIN_ALPHA);
0930 }
0931
0932 if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit))
0933 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
0934 else
0935 state->rf_gain_limit += top_delta;
0936
0937 if (state->rf_gain_limit < 0)
0938 state->rf_gain_limit = 0;
0939
0940
0941 gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
0942 if (gain_delta >= ((s16) gain - state->current_gain))
0943 state->current_gain = gain;
0944 else
0945 state->current_gain += gain_delta;
0946
0947 if (state->current_gain < 0)
0948 state->current_gain = 0;
0949
0950
0951 gain = state->current_gain >> GAIN_ALPHA;
0952
0953
0954 if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
0955 rf = state->rf_gain_limit >> WBD_ALPHA;
0956 bb = gain - rf;
0957 if (bb > state->bb_ramp[0])
0958 bb = state->bb_ramp[0];
0959 } else {
0960 rf = gain;
0961 bb = 0;
0962 }
0963
0964 state->gain[0] = rf;
0965 state->gain[1] = bb;
0966
0967
0968
0969 g = state->rf_ramp + 1;
0970 ref = rf;
0971 for (i = 0; i < 7; i++) {
0972 if (g[0] == 0 || ref < (g[1] - g[0]))
0973 v = 0;
0974 else if (ref >= g[1])
0975 v = g[2];
0976 else
0977 v = ((ref - (g[1] - g[0])) * g[2]) / g[0];
0978
0979 if (i == 0)
0980 gain_reg[0] = v;
0981 else if (i == 1)
0982 gain_reg[0] |= v << 7;
0983 else if (i == 2)
0984 gain_reg[1] = v;
0985 else if (i == 3)
0986 gain_reg[1] |= v << 7;
0987 else if (i == 4)
0988 gain_reg[2] = v | state->rf_lt_def;
0989 else if (i == 5)
0990 gain_reg[3] = v << 3;
0991 else if (i == 6)
0992 gain_reg[3] |= v << 8;
0993
0994 g += 3;
0995
0996
0997 if (i == 4) {
0998 g = state->bb_ramp + 1;
0999 ref = bb;
1000 }
1001 }
1002 gain_reg[3] |= state->bb_1_def;
1003 gain_reg[3] |= ((bb % 10) * 100) / 125;
1004
1005 #ifdef DEBUG_AGC
1006 dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x\n", rf, bb, rf + bb,
1007 gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]);
1008 #endif
1009
1010
1011 for (i = 0; i < 4; i++) {
1012 v = gain_reg[i];
1013 if (force || state->gain_reg[i] != v) {
1014 state->gain_reg[i] = v;
1015 dib0090_write_reg(state, gain_reg_addr[i], v);
1016 }
1017 }
1018 }
1019
1020 static void dib0090_set_boost(struct dib0090_state *state, int onoff)
1021 {
1022 state->bb_1_def &= 0xdfff;
1023 state->bb_1_def |= onoff << 13;
1024 }
1025
1026 static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
1027 {
1028 state->rf_ramp = cfg;
1029 }
1030
1031 static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
1032 {
1033 state->rf_ramp = cfg;
1034
1035 dib0090_write_reg(state, 0x2a, 0xffff);
1036
1037 dprintk("total RF gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
1038
1039 dib0090_write_regs(state, 0x2c, cfg + 3, 6);
1040 dib0090_write_regs(state, 0x3e, cfg + 9, 2);
1041 }
1042
1043 static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
1044 {
1045 state->bb_ramp = cfg;
1046 dib0090_set_boost(state, cfg[0] > 500);
1047 }
1048
1049 static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
1050 {
1051 state->bb_ramp = cfg;
1052
1053 dib0090_set_boost(state, cfg[0] > 500);
1054
1055 dib0090_write_reg(state, 0x33, 0xffff);
1056 dprintk("total BB gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x33));
1057 dib0090_write_regs(state, 0x35, cfg + 3, 4);
1058 }
1059
1060 void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
1061 {
1062 struct dib0090_state *state = fe->tuner_priv;
1063 const u16 *bb_ramp = bb_ramp_pwm_normal;
1064 const u16 *rf_ramp = NULL;
1065 u8 en_pwm_rf_mux = 1;
1066
1067
1068 if (state->config->use_pwm_agc) {
1069 if (state->current_band == BAND_CBAND) {
1070 if (state->identity.in_soc) {
1071 bb_ramp = bb_ramp_pwm_normal_socs;
1072 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1073 rf_ramp = rf_ramp_pwm_cband_8090;
1074 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) {
1075 if (state->config->is_dib7090e) {
1076 if (state->rf_ramp == NULL)
1077 rf_ramp = rf_ramp_pwm_cband_7090e_sensitivity;
1078 else
1079 rf_ramp = state->rf_ramp;
1080 } else
1081 rf_ramp = rf_ramp_pwm_cband_7090p;
1082 }
1083 } else
1084 rf_ramp = rf_ramp_pwm_cband;
1085 } else
1086
1087 if (state->current_band == BAND_VHF) {
1088 if (state->identity.in_soc) {
1089 bb_ramp = bb_ramp_pwm_normal_socs;
1090
1091 } else
1092 rf_ramp = rf_ramp_pwm_vhf;
1093 } else if (state->current_band == BAND_UHF) {
1094 if (state->identity.in_soc) {
1095 bb_ramp = bb_ramp_pwm_normal_socs;
1096 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1097 rf_ramp = rf_ramp_pwm_uhf_8090;
1098 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1099 rf_ramp = rf_ramp_pwm_uhf_7090;
1100 } else
1101 rf_ramp = rf_ramp_pwm_uhf;
1102 }
1103 if (rf_ramp)
1104 dib0090_set_rframp_pwm(state, rf_ramp);
1105 dib0090_set_bbramp_pwm(state, bb_ramp);
1106
1107
1108 if (state->rf_ramp)
1109 dprintk("ramp RF gain = %d BAND = %s version = %d\n",
1110 state->rf_ramp[0],
1111 (state->current_band == BAND_CBAND) ? "CBAND" : "NOT CBAND",
1112 state->identity.version & 0x1f);
1113
1114 if (rf_ramp && ((state->rf_ramp && state->rf_ramp[0] == 0) ||
1115 (state->current_band == BAND_CBAND &&
1116 (state->identity.version & 0x1f) <= P1D_E_F))) {
1117 dprintk("DE-Engage mux for direct gain reg control\n");
1118 en_pwm_rf_mux = 0;
1119 } else
1120 dprintk("Engage mux for PWM control\n");
1121
1122 dib0090_write_reg(state, 0x32, (en_pwm_rf_mux << 12) | (en_pwm_rf_mux << 11));
1123
1124
1125 if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1126 dib0090_write_reg(state, 0x04, 3);
1127 else
1128 dib0090_write_reg(state, 0x04, 1);
1129 dib0090_write_reg(state, 0x39, (1 << 10));
1130 }
1131 }
1132 EXPORT_SYMBOL(dib0090_pwm_gain_reset);
1133
1134 void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
1135 {
1136 struct dib0090_state *state = fe->tuner_priv;
1137 if (DC_servo_cutoff < 4)
1138 dib0090_write_reg(state, 0x04, DC_servo_cutoff);
1139 }
1140 EXPORT_SYMBOL(dib0090_set_dc_servo);
1141
1142 static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
1143 {
1144 u16 adc_val = dib0090_read_reg(state, 0x1d);
1145 if (state->identity.in_soc)
1146 adc_val >>= 2;
1147 return adc_val;
1148 }
1149
1150 int dib0090_gain_control(struct dvb_frontend *fe)
1151 {
1152 struct dib0090_state *state = fe->tuner_priv;
1153 enum frontend_tune_state *tune_state = &state->tune_state;
1154 int ret = 10;
1155
1156 u16 wbd_val = 0;
1157 u8 apply_gain_immediatly = 1;
1158 s16 wbd_error = 0, adc_error = 0;
1159
1160 if (*tune_state == CT_AGC_START) {
1161 state->agc_freeze = 0;
1162 dib0090_write_reg(state, 0x04, 0x0);
1163
1164 #ifdef CONFIG_BAND_SBAND
1165 if (state->current_band == BAND_SBAND) {
1166 dib0090_set_rframp(state, rf_ramp_sband);
1167 dib0090_set_bbramp(state, bb_ramp_boost);
1168 } else
1169 #endif
1170 #ifdef CONFIG_BAND_VHF
1171 if (state->current_band == BAND_VHF && !state->identity.p1g) {
1172 dib0090_set_rframp(state, rf_ramp_pwm_vhf);
1173 dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1174 } else
1175 #endif
1176 #ifdef CONFIG_BAND_CBAND
1177 if (state->current_band == BAND_CBAND && !state->identity.p1g) {
1178 dib0090_set_rframp(state, rf_ramp_pwm_cband);
1179 dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1180 } else
1181 #endif
1182 if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
1183 dib0090_set_rframp(state, rf_ramp_pwm_cband_7090p);
1184 dib0090_set_bbramp(state, bb_ramp_pwm_normal_socs);
1185 } else {
1186 dib0090_set_rframp(state, rf_ramp_pwm_uhf);
1187 dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1188 }
1189
1190 dib0090_write_reg(state, 0x32, 0);
1191 dib0090_write_reg(state, 0x39, 0);
1192
1193 dib0090_wbd_target(state, state->current_rf);
1194
1195 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
1196 state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
1197
1198 *tune_state = CT_AGC_STEP_0;
1199 } else if (!state->agc_freeze) {
1200 s16 wbd = 0, i, cnt;
1201
1202 int adc;
1203 wbd_val = dib0090_get_slow_adc_val(state);
1204
1205 if (*tune_state == CT_AGC_STEP_0)
1206 cnt = 5;
1207 else
1208 cnt = 1;
1209
1210 for (i = 0; i < cnt; i++) {
1211 wbd_val = dib0090_get_slow_adc_val(state);
1212 wbd += dib0090_wbd_to_db(state, wbd_val);
1213 }
1214 wbd /= cnt;
1215 wbd_error = state->wbd_target - wbd;
1216
1217 if (*tune_state == CT_AGC_STEP_0) {
1218 if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) {
1219 #ifdef CONFIG_BAND_CBAND
1220
1221 u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
1222 if (state->current_band == BAND_CBAND && ltg2) {
1223 ltg2 >>= 1;
1224 state->rf_lt_def &= ltg2 << 10;
1225 }
1226 #endif
1227 } else {
1228 state->agc_step = 0;
1229 *tune_state = CT_AGC_STEP_1;
1230 }
1231 } else {
1232
1233 adc = state->config->get_adc_power(fe);
1234 adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21;
1235
1236 adc_error = (s16) (((s32) ADC_TARGET) - adc);
1237 #ifdef CONFIG_STANDARD_DAB
1238 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
1239 adc_error -= 10;
1240 #endif
1241 #ifdef CONFIG_STANDARD_DVBT
1242 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
1243 (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
1244 adc_error += 60;
1245 #endif
1246 #ifdef CONFIG_SYS_ISDBT
1247 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
1248 0)
1249 &&
1250 ((state->fe->dtv_property_cache.layer[0].modulation ==
1251 QAM_64)
1252 || (state->fe->dtv_property_cache.
1253 layer[0].modulation == QAM_16)))
1254 ||
1255 ((state->fe->dtv_property_cache.layer[1].segment_count >
1256 0)
1257 &&
1258 ((state->fe->dtv_property_cache.layer[1].modulation ==
1259 QAM_64)
1260 || (state->fe->dtv_property_cache.
1261 layer[1].modulation == QAM_16)))
1262 ||
1263 ((state->fe->dtv_property_cache.layer[2].segment_count >
1264 0)
1265 &&
1266 ((state->fe->dtv_property_cache.layer[2].modulation ==
1267 QAM_64)
1268 || (state->fe->dtv_property_cache.
1269 layer[2].modulation == QAM_16)))
1270 )
1271 )
1272 adc_error += 60;
1273 #endif
1274
1275 if (*tune_state == CT_AGC_STEP_1) {
1276 if (abs(adc_error) < 50 || state->agc_step++ > 5) {
1277
1278 #ifdef CONFIG_STANDARD_DAB
1279 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
1280 dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63));
1281 dib0090_write_reg(state, 0x04, 0x0);
1282 } else
1283 #endif
1284 {
1285 dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
1286 dib0090_write_reg(state, 0x04, 0x01);
1287 }
1288
1289 *tune_state = CT_AGC_STOP;
1290 }
1291 } else {
1292
1293 ret = 100;
1294 apply_gain_immediatly = 0;
1295 }
1296 }
1297 #ifdef DEBUG_AGC
1298 dprintk
1299 ("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
1300 (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
1301 (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
1302 #endif
1303 }
1304
1305
1306 if (!state->agc_freeze)
1307 dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
1308 return ret;
1309 }
1310
1311 EXPORT_SYMBOL(dib0090_gain_control);
1312
1313 void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
1314 {
1315 struct dib0090_state *state = fe->tuner_priv;
1316 if (rf)
1317 *rf = state->gain[0];
1318 if (bb)
1319 *bb = state->gain[1];
1320 if (rf_gain_limit)
1321 *rf_gain_limit = state->rf_gain_limit;
1322 if (rflt)
1323 *rflt = (state->rf_lt_def >> 10) & 0x7;
1324 }
1325
1326 EXPORT_SYMBOL(dib0090_get_current_gain);
1327
1328 u16 dib0090_get_wbd_target(struct dvb_frontend *fe)
1329 {
1330 struct dib0090_state *state = fe->tuner_priv;
1331 u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
1332 s32 current_temp = state->temperature;
1333 s32 wbd_thot, wbd_tcold;
1334 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1335
1336 while (f_MHz > wbd->max_freq)
1337 wbd++;
1338
1339 dprintk("using wbd-table-entry with max freq %d\n", wbd->max_freq);
1340
1341 if (current_temp < 0)
1342 current_temp = 0;
1343 if (current_temp > 128)
1344 current_temp = 128;
1345
1346 state->wbdmux &= ~(7 << 13);
1347 if (wbd->wbd_gain != 0)
1348 state->wbdmux |= (wbd->wbd_gain << 13);
1349 else
1350 state->wbdmux |= (4 << 13);
1351
1352 dib0090_write_reg(state, 0x10, state->wbdmux);
1353
1354 wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6);
1355 wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6);
1356
1357 wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7;
1358
1359 state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold);
1360 dprintk("wbd-target: %d dB\n", (u32) state->wbd_target);
1361 dprintk("wbd offset applied is %d\n", wbd_tcold);
1362
1363 return state->wbd_offset + wbd_tcold;
1364 }
1365 EXPORT_SYMBOL(dib0090_get_wbd_target);
1366
1367 u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
1368 {
1369 struct dib0090_state *state = fe->tuner_priv;
1370 return state->wbd_offset;
1371 }
1372 EXPORT_SYMBOL(dib0090_get_wbd_offset);
1373
1374 int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3)
1375 {
1376 struct dib0090_state *state = fe->tuner_priv;
1377
1378 dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8)
1379 | ((sw3 & 1) << 2) | ((sw2 & 1) << 1) | (sw1 & 1));
1380
1381 return 0;
1382 }
1383 EXPORT_SYMBOL(dib0090_set_switch);
1384
1385 int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff)
1386 {
1387 struct dib0090_state *state = fe->tuner_priv;
1388
1389 dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff)
1390 | ((onoff & 1) << 15));
1391 return 0;
1392 }
1393 EXPORT_SYMBOL(dib0090_set_vga);
1394
1395 int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity)
1396 {
1397 struct dib0090_state *state = fe->tuner_priv;
1398
1399 if ((!state->identity.p1g) || (!state->identity.in_soc)
1400 || ((state->identity.version != SOC_7090_P1G_21R1)
1401 && (state->identity.version != SOC_7090_P1G_11R1))) {
1402 dprintk("%s() function can only be used for dib7090P\n", __func__);
1403 return -ENODEV;
1404 }
1405
1406 if (cfg_sensitivity)
1407 state->rf_ramp = rf_ramp_pwm_cband_7090e_sensitivity;
1408 else
1409 state->rf_ramp = rf_ramp_pwm_cband_7090e_aci;
1410 dib0090_pwm_gain_reset(fe);
1411
1412 return 0;
1413 }
1414 EXPORT_SYMBOL(dib0090_update_rframp_7090);
1415
1416 static const u16 dib0090_defaults[] = {
1417
1418 25, 0x01,
1419 0x0000,
1420 0x99a0,
1421 0x6008,
1422 0x0000,
1423 0x8bcb,
1424 0x0000,
1425 0x0405,
1426 0x0000,
1427 0x0000,
1428 0x0000,
1429 0xb802,
1430 0x0300,
1431 0x2d12,
1432 0xbac0,
1433 0x7c00,
1434 0xdbb9,
1435 0x0954,
1436 0x0743,
1437 0x8000,
1438 0x0001,
1439 0x0040,
1440 0x0100,
1441 0x0000,
1442 0xe910,
1443 0x149e,
1444
1445 1, 0x1c,
1446 0xff2d,
1447
1448 1, 0x39,
1449 0x0000,
1450
1451 2, 0x1e,
1452 0x07FF,
1453 0x0007,
1454
1455 1, 0x24,
1456 EN_UHF | EN_CRYSTAL,
1457
1458 2, 0x3c,
1459 0x3ff,
1460 0x111,
1461 0
1462 };
1463
1464 static const u16 dib0090_p1g_additionnal_defaults[] = {
1465 1, 0x05,
1466 0xabcd,
1467
1468 1, 0x11,
1469 0x00b4,
1470
1471 1, 0x1c,
1472 0xfffd,
1473
1474 1, 0x40,
1475 0x108,
1476 0
1477 };
1478
1479 static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n)
1480 {
1481 u16 l, r;
1482
1483 l = pgm_read_word(n++);
1484 while (l) {
1485 r = pgm_read_word(n++);
1486 do {
1487 dib0090_write_reg(state, r, pgm_read_word(n++));
1488 r++;
1489 } while (--l);
1490 l = pgm_read_word(n++);
1491 }
1492 }
1493
1494 #define CAP_VALUE_MIN (u8) 9
1495 #define CAP_VALUE_MAX (u8) 40
1496 #define HR_MIN (u8) 25
1497 #define HR_MAX (u8) 40
1498 #define POLY_MIN (u8) 0
1499 #define POLY_MAX (u8) 8
1500
1501 static void dib0090_set_EFUSE(struct dib0090_state *state)
1502 {
1503 u8 c, h, n;
1504 u16 e2, e4;
1505 u16 cal;
1506
1507 e2 = dib0090_read_reg(state, 0x26);
1508 e4 = dib0090_read_reg(state, 0x28);
1509
1510 if ((state->identity.version == P1D_E_F) ||
1511 (state->identity.version == P1G) || (e2 == 0xffff)) {
1512
1513 dib0090_write_reg(state, 0x22, 0x10);
1514 cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff;
1515
1516 if ((cal < 670) || (cal == 1023))
1517 cal = 850;
1518 n = 165 - ((cal * 10)>>6) ;
1519 e2 = e4 = (3<<12) | (34<<6) | (n);
1520 }
1521
1522 if (e2 != e4)
1523 e2 &= e4;
1524
1525 if (e2 != 0xffff) {
1526 c = e2 & 0x3f;
1527 n = (e2 >> 12) & 0xf;
1528 h = (e2 >> 6) & 0x3f;
1529
1530 if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
1531 c = 32;
1532 else
1533 c += 14;
1534 if ((h >= HR_MAX) || (h <= HR_MIN))
1535 h = 34;
1536 if ((n >= POLY_MAX) || (n <= POLY_MIN))
1537 n = 3;
1538
1539 dib0090_write_reg(state, 0x13, (h << 10));
1540 e2 = (n << 11) | ((h >> 2)<<6) | c;
1541 dib0090_write_reg(state, 0x2, e2);
1542 }
1543 }
1544
1545 static int dib0090_reset(struct dvb_frontend *fe)
1546 {
1547 struct dib0090_state *state = fe->tuner_priv;
1548
1549 dib0090_reset_digital(fe, state->config);
1550 if (dib0090_identify(fe) < 0)
1551 return -EIO;
1552
1553 #ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
1554 if (!(state->identity.version & 0x1))
1555 return 0;
1556 #endif
1557
1558 if (!state->identity.in_soc) {
1559 if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2)
1560 dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1561 else
1562 dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1563 }
1564
1565 dib0090_set_default_config(state, dib0090_defaults);
1566
1567 if (state->identity.in_soc)
1568 dib0090_write_reg(state, 0x18, 0x2910);
1569
1570 if (state->identity.p1g)
1571 dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults);
1572
1573
1574 if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc))
1575 dib0090_set_EFUSE(state);
1576
1577
1578 if (state->config->force_crystal_mode != 0)
1579 dib0090_write_reg(state, 0x14,
1580 state->config->force_crystal_mode & 3);
1581 else if (state->config->io.clock_khz >= 24000)
1582 dib0090_write_reg(state, 0x14, 1);
1583 else
1584 dib0090_write_reg(state, 0x14, 2);
1585 dprintk("Pll lock : %d\n", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
1586
1587 state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL;
1588
1589 return 0;
1590 }
1591
1592 #define steps(u) (((u) > 15) ? ((u)-16) : (u))
1593 #define INTERN_WAIT 10
1594 static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1595 {
1596 int ret = INTERN_WAIT * 10;
1597
1598 switch (*tune_state) {
1599 case CT_TUNER_STEP_2:
1600
1601 dib0090_write_reg(state, 0x1f, 0x7);
1602 *tune_state = CT_TUNER_STEP_3;
1603 break;
1604
1605 case CT_TUNER_STEP_3:
1606 state->adc_diff = dib0090_read_reg(state, 0x1d);
1607
1608
1609 dib0090_write_reg(state, 0x1f, 0x4);
1610 *tune_state = CT_TUNER_STEP_4;
1611 break;
1612
1613 case CT_TUNER_STEP_4:
1614 state->adc_diff -= dib0090_read_reg(state, 0x1d);
1615 *tune_state = CT_TUNER_STEP_5;
1616 ret = 0;
1617 break;
1618
1619 default:
1620 break;
1621 }
1622
1623 return ret;
1624 }
1625
1626 struct dc_calibration {
1627 u8 addr;
1628 u8 offset;
1629 u8 pga:1;
1630 u16 bb1;
1631 u8 i:1;
1632 };
1633
1634 static const struct dc_calibration dc_table[] = {
1635
1636 {0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1},
1637 {0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0},
1638
1639 {0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1},
1640 {0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0},
1641 {0},
1642 };
1643
1644 static const struct dc_calibration dc_p1g_table[] = {
1645
1646
1647 {0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1},
1648 {0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0},
1649
1650 {0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1},
1651 {0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0},
1652 {0},
1653 };
1654
1655 static void dib0090_set_trim(struct dib0090_state *state)
1656 {
1657 u16 *val;
1658
1659 if (state->dc->addr == 0x07)
1660 val = &state->bb7;
1661 else
1662 val = &state->bb6;
1663
1664 *val &= ~(0x1f << state->dc->offset);
1665 *val |= state->step << state->dc->offset;
1666
1667 dib0090_write_reg(state, state->dc->addr, *val);
1668 }
1669
1670 static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1671 {
1672 int ret = 0;
1673 u16 reg;
1674
1675 switch (*tune_state) {
1676 case CT_TUNER_START:
1677 dprintk("Start DC offset calibration");
1678
1679
1680 state->bb6 = 0;
1681 state->bb7 = 0x040d;
1682
1683
1684 reg = dib0090_read_reg(state, 0x24) & 0x0ffb;
1685 dib0090_write_reg(state, 0x24, reg);
1686
1687 state->wbdmux = dib0090_read_reg(state, 0x10);
1688 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3);
1689 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
1690
1691 state->dc = dc_table;
1692
1693 if (state->identity.p1g)
1694 state->dc = dc_p1g_table;
1695
1696 fallthrough;
1697 case CT_TUNER_STEP_0:
1698 dprintk("Start/continue DC calibration for %s path\n",
1699 (state->dc->i == 1) ? "I" : "Q");
1700 dib0090_write_reg(state, 0x01, state->dc->bb1);
1701 dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
1702
1703 state->step = 0;
1704 state->min_adc_diff = 1023;
1705 *tune_state = CT_TUNER_STEP_1;
1706 ret = 50;
1707 break;
1708
1709 case CT_TUNER_STEP_1:
1710 dib0090_set_trim(state);
1711 *tune_state = CT_TUNER_STEP_2;
1712 break;
1713
1714 case CT_TUNER_STEP_2:
1715 case CT_TUNER_STEP_3:
1716 case CT_TUNER_STEP_4:
1717 ret = dib0090_get_offset(state, tune_state);
1718 break;
1719
1720 case CT_TUNER_STEP_5:
1721 dprintk("adc_diff = %d, current step= %d\n", (u32) state->adc_diff, state->step);
1722 if (state->step == 0 && state->adc_diff < 0) {
1723 state->min_adc_diff = -1023;
1724 dprintk("Change of sign of the minimum adc diff\n");
1725 }
1726
1727 dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d\n", state->adc_diff, state->min_adc_diff, state->step);
1728
1729
1730 if (state->step == 0) {
1731 if (state->dc->pga && state->adc_diff < 0)
1732 state->step = 0x10;
1733 if (state->dc->pga == 0 && state->adc_diff > 0)
1734 state->step = 0x10;
1735 }
1736
1737
1738 if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) {
1739
1740 state->step++;
1741 state->min_adc_diff = state->adc_diff;
1742 *tune_state = CT_TUNER_STEP_1;
1743 } else {
1744
1745 if (abs(state->adc_diff) > abs(state->min_adc_diff)) {
1746 dprintk("Since adc_diff N = %d > adc_diff step N-1 = %d, Come back one step\n", state->adc_diff, state->min_adc_diff);
1747 state->step--;
1748 }
1749
1750 dib0090_set_trim(state);
1751 dprintk("BB Offset Cal, BBreg=%u,Offset=%d,Value Set=%d\n",
1752 state->dc->addr, state->adc_diff, state->step);
1753
1754 state->dc++;
1755 if (state->dc->addr == 0)
1756 *tune_state = CT_TUNER_STEP_6;
1757 else
1758 *tune_state = CT_TUNER_STEP_0;
1759
1760 }
1761 break;
1762
1763 case CT_TUNER_STEP_6:
1764 dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
1765 dib0090_write_reg(state, 0x1f, 0x7);
1766 *tune_state = CT_TUNER_START;
1767 state->calibrate &= ~DC_CAL;
1768 break;
1769
1770 default:
1771 break;
1772 }
1773 return ret;
1774 }
1775
1776 static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1777 {
1778 u8 wbd_gain;
1779 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1780
1781 switch (*tune_state) {
1782 case CT_TUNER_START:
1783 while (state->current_rf / 1000 > wbd->max_freq)
1784 wbd++;
1785 if (wbd->wbd_gain != 0)
1786 wbd_gain = wbd->wbd_gain;
1787 else {
1788 wbd_gain = 4;
1789 #if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1790 if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
1791 wbd_gain = 2;
1792 #endif
1793 }
1794
1795 if (wbd_gain == state->wbd_calibration_gain) {
1796 *tune_state = CT_TUNER_START;
1797 state->calibrate &= ~WBD_CAL;
1798 return 0;
1799 }
1800
1801 dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
1802
1803 dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
1804 *tune_state = CT_TUNER_STEP_0;
1805 state->wbd_calibration_gain = wbd_gain;
1806 return 90;
1807
1808 case CT_TUNER_STEP_0:
1809 state->wbd_offset = dib0090_get_slow_adc_val(state);
1810 dprintk("WBD calibration offset = %d\n", state->wbd_offset);
1811 *tune_state = CT_TUNER_START;
1812 state->calibrate &= ~WBD_CAL;
1813 break;
1814
1815 default:
1816 break;
1817 }
1818 return 0;
1819 }
1820
1821 static void dib0090_set_bandwidth(struct dib0090_state *state)
1822 {
1823 u16 tmp;
1824
1825 if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
1826 tmp = (3 << 14);
1827 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
1828 tmp = (2 << 14);
1829 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
1830 tmp = (1 << 14);
1831 else
1832 tmp = (0 << 14);
1833
1834 state->bb_1_def &= 0x3fff;
1835 state->bb_1_def |= tmp;
1836
1837 dib0090_write_reg(state, 0x01, state->bb_1_def);
1838
1839 dib0090_write_reg(state, 0x03, 0x6008);
1840 dib0090_write_reg(state, 0x04, 0x1);
1841 if (state->identity.in_soc) {
1842 dib0090_write_reg(state, 0x05, 0x9bcf);
1843 } else {
1844 dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f));
1845 dib0090_write_reg(state, 0x05, 0xabcd);
1846 }
1847 }
1848
1849 static const struct dib0090_pll dib0090_pll_table[] = {
1850 #ifdef CONFIG_BAND_CBAND
1851 {56000, 0, 9, 48, 6},
1852 {70000, 1, 9, 48, 6},
1853 {87000, 0, 8, 32, 4},
1854 {105000, 1, 8, 32, 4},
1855 {115000, 0, 7, 24, 6},
1856 {140000, 1, 7, 24, 6},
1857 {170000, 0, 6, 16, 4},
1858 #endif
1859 #ifdef CONFIG_BAND_VHF
1860 {200000, 1, 6, 16, 4},
1861 {230000, 0, 5, 12, 6},
1862 {280000, 1, 5, 12, 6},
1863 {340000, 0, 4, 8, 4},
1864 {380000, 1, 4, 8, 4},
1865 {450000, 0, 3, 6, 6},
1866 #endif
1867 #ifdef CONFIG_BAND_UHF
1868 {580000, 1, 3, 6, 6},
1869 {700000, 0, 2, 4, 4},
1870 {860000, 1, 2, 4, 4},
1871 #endif
1872 #ifdef CONFIG_BAND_LBAND
1873 {1800000, 1, 0, 2, 4},
1874 #endif
1875 #ifdef CONFIG_BAND_SBAND
1876 {2900000, 0, 14, 1, 4},
1877 #endif
1878 };
1879
1880 static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
1881
1882 #ifdef CONFIG_BAND_CBAND
1883 {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1884 {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1885 {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1886 #endif
1887 #ifdef CONFIG_BAND_UHF
1888 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1889 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1890 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1891 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1892 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1893 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1894 #endif
1895 #ifdef CONFIG_BAND_LBAND
1896 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1897 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1898 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1899 #endif
1900 #ifdef CONFIG_BAND_SBAND
1901 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1902 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1903 #endif
1904 };
1905
1906 static const struct dib0090_tuning dib0090_tuning_table[] = {
1907
1908 #ifdef CONFIG_BAND_CBAND
1909 {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1910 #endif
1911 #ifdef CONFIG_BAND_VHF
1912 {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1913 {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1914 {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1915 #endif
1916 #ifdef CONFIG_BAND_UHF
1917 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1918 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1919 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1920 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1921 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1922 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1923 #endif
1924 #ifdef CONFIG_BAND_LBAND
1925 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1926 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1927 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1928 #endif
1929 #ifdef CONFIG_BAND_SBAND
1930 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1931 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1932 #endif
1933 };
1934
1935 static const struct dib0090_tuning dib0090_p1g_tuning_table[] = {
1936 #ifdef CONFIG_BAND_CBAND
1937 {170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB},
1938 #endif
1939 #ifdef CONFIG_BAND_VHF
1940 {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1941 {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1942 {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1943 #endif
1944 #ifdef CONFIG_BAND_UHF
1945 {510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1946 {540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1947 {600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1948 {630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1949 {680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1950 {720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1951 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1952 #endif
1953 #ifdef CONFIG_BAND_LBAND
1954 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1955 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1956 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1957 #endif
1958 #ifdef CONFIG_BAND_SBAND
1959 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1960 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1961 #endif
1962 };
1963
1964 static const struct dib0090_pll dib0090_p1g_pll_table[] = {
1965 #ifdef CONFIG_BAND_CBAND
1966 {57000, 0, 11, 48, 6},
1967 {70000, 1, 11, 48, 6},
1968 {86000, 0, 10, 32, 4},
1969 {105000, 1, 10, 32, 4},
1970 {115000, 0, 9, 24, 6},
1971 {140000, 1, 9, 24, 6},
1972 {170000, 0, 8, 16, 4},
1973 #endif
1974 #ifdef CONFIG_BAND_VHF
1975 {200000, 1, 8, 16, 4},
1976 {230000, 0, 7, 12, 6},
1977 {280000, 1, 7, 12, 6},
1978 {340000, 0, 6, 8, 4},
1979 {380000, 1, 6, 8, 4},
1980 {455000, 0, 5, 6, 6},
1981 #endif
1982 #ifdef CONFIG_BAND_UHF
1983 {580000, 1, 5, 6, 6},
1984 {680000, 0, 4, 4, 4},
1985 {860000, 1, 4, 4, 4},
1986 #endif
1987 #ifdef CONFIG_BAND_LBAND
1988 {1800000, 1, 2, 2, 4},
1989 #endif
1990 #ifdef CONFIG_BAND_SBAND
1991 {2900000, 0, 1, 1, 6},
1992 #endif
1993 };
1994
1995 static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = {
1996 #ifdef CONFIG_BAND_CBAND
1997 {184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1998 {227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1999 {380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
2000 #endif
2001 #ifdef CONFIG_BAND_UHF
2002 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2003 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2004 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2005 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2006 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2007 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2008 #endif
2009 #ifdef CONFIG_BAND_LBAND
2010 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2011 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2012 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2013 #endif
2014 #ifdef CONFIG_BAND_SBAND
2015 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
2016 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
2017 #endif
2018 };
2019
2020 static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = {
2021 #ifdef CONFIG_BAND_CBAND
2022 {300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2023 {380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2024 {570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2025 {858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2026 #endif
2027 };
2028
2029 static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = {
2030 #ifdef CONFIG_BAND_CBAND
2031 { 300000, 0 , 3, 0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2032 { 380000, 0 , 10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2033 { 600000, 0 , 10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2034 { 660000, 0 , 5, 0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB },
2035 { 720000, 0 , 5, 0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2036 { 860000, 0 , 4, 0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB },
2037 #endif
2038 };
2039
2040 int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
2041 u8 cfg_sensitivity)
2042 {
2043 struct dib0090_state *state = fe->tuner_priv;
2044 const struct dib0090_tuning *tune =
2045 dib0090_tuning_table_cband_7090e_sensitivity;
2046 static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = {
2047 { 300000, 0 , 3, 0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2048 { 650000, 0 , 4, 0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB },
2049 { 860000, 0 , 5, 0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB },
2050 };
2051
2052 if ((!state->identity.p1g) || (!state->identity.in_soc)
2053 || ((state->identity.version != SOC_7090_P1G_21R1)
2054 && (state->identity.version != SOC_7090_P1G_11R1))) {
2055 dprintk("%s() function can only be used for dib7090\n", __func__);
2056 return -ENODEV;
2057 }
2058
2059 if (cfg_sensitivity)
2060 tune = dib0090_tuning_table_cband_7090e_sensitivity;
2061 else
2062 tune = dib0090_tuning_table_cband_7090e_aci;
2063
2064 while (state->rf_request > tune->max_freq)
2065 tune++;
2066
2067 dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000)
2068 | (tune->lna_bias & 0x7fff));
2069 dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f)
2070 | ((tune->lna_tune << 6) & 0x07c0));
2071 return 0;
2072 }
2073 EXPORT_SYMBOL(dib0090_update_tuning_table_7090);
2074
2075 static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2076 {
2077 int ret = 0;
2078 u16 lo4 = 0xe900;
2079
2080 s16 adc_target;
2081 u16 adc;
2082 s8 step_sign;
2083 u8 force_soft_search = 0;
2084
2085 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
2086 force_soft_search = 1;
2087
2088 if (*tune_state == CT_TUNER_START) {
2089 dprintk("Start Captrim search : %s\n",
2090 (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO");
2091 dib0090_write_reg(state, 0x10, 0x2B1);
2092 dib0090_write_reg(state, 0x1e, 0x0032);
2093
2094 if (!state->tuner_is_tuned) {
2095
2096 if (!state->identity.p1g || force_soft_search)
2097 state->step = state->captrim = state->fcaptrim = 64;
2098
2099 state->current_rf = state->rf_request;
2100 } else {
2101 if (!state->identity.p1g || force_soft_search) {
2102
2103 state->step = 4;
2104 state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
2105 }
2106 }
2107 state->adc_diff = 3000;
2108 *tune_state = CT_TUNER_STEP_0;
2109
2110 } else if (*tune_state == CT_TUNER_STEP_0) {
2111 if (state->identity.p1g && !force_soft_search) {
2112 u8 ratio = 31;
2113
2114 dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
2115 dib0090_read_reg(state, 0x40);
2116 ret = 50;
2117 } else {
2118 state->step /= 2;
2119 dib0090_write_reg(state, 0x18, lo4 | state->captrim);
2120
2121 if (state->identity.in_soc)
2122 ret = 25;
2123 }
2124 *tune_state = CT_TUNER_STEP_1;
2125
2126 } else if (*tune_state == CT_TUNER_STEP_1) {
2127 if (state->identity.p1g && !force_soft_search) {
2128 dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
2129 dib0090_read_reg(state, 0x40);
2130
2131 state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
2132 dprintk("***Final Captrim= 0x%x\n", state->fcaptrim);
2133 *tune_state = CT_TUNER_STEP_3;
2134
2135 } else {
2136
2137 adc = dib0090_get_slow_adc_val(state);
2138 dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV\n", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
2139
2140 if (state->rest == 0 || state->identity.in_soc) {
2141 adc_target = 200;
2142 } else
2143 adc_target = 400;
2144
2145 if (adc >= adc_target) {
2146 adc -= adc_target;
2147 step_sign = -1;
2148 } else {
2149 adc = adc_target - adc;
2150 step_sign = 1;
2151 }
2152
2153 if (adc < state->adc_diff) {
2154 dprintk("CAPTRIM=%d is closer to target (%d/%d)\n", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
2155 state->adc_diff = adc;
2156 state->fcaptrim = state->captrim;
2157 }
2158
2159 state->captrim += step_sign * state->step;
2160 if (state->step >= 1)
2161 *tune_state = CT_TUNER_STEP_0;
2162 else
2163 *tune_state = CT_TUNER_STEP_2;
2164
2165 ret = 25;
2166 }
2167 } else if (*tune_state == CT_TUNER_STEP_2) {
2168
2169 dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
2170
2171 *tune_state = CT_TUNER_STEP_3;
2172
2173 } else if (*tune_state == CT_TUNER_STEP_3) {
2174 state->calibrate &= ~CAPTRIM_CAL;
2175 *tune_state = CT_TUNER_STEP_0;
2176 }
2177
2178 return ret;
2179 }
2180
2181 static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2182 {
2183 int ret = 15;
2184 s16 val;
2185
2186 switch (*tune_state) {
2187 case CT_TUNER_START:
2188 state->wbdmux = dib0090_read_reg(state, 0x10);
2189 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
2190
2191 state->bias = dib0090_read_reg(state, 0x13);
2192 dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
2193
2194 *tune_state = CT_TUNER_STEP_0;
2195
2196 break;
2197
2198 case CT_TUNER_STEP_0:
2199 state->adc_diff = dib0090_get_slow_adc_val(state);
2200 dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
2201 *tune_state = CT_TUNER_STEP_1;
2202 break;
2203
2204 case CT_TUNER_STEP_1:
2205 val = dib0090_get_slow_adc_val(state);
2206 state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
2207
2208 dprintk("temperature: %d C\n", state->temperature - 30);
2209
2210 *tune_state = CT_TUNER_STEP_2;
2211 break;
2212
2213 case CT_TUNER_STEP_2:
2214 dib0090_write_reg(state, 0x13, state->bias);
2215 dib0090_write_reg(state, 0x10, state->wbdmux);
2216
2217 *tune_state = CT_TUNER_START;
2218 state->calibrate &= ~TEMP_CAL;
2219 if (state->config->analog_output == 0)
2220 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2221
2222 break;
2223
2224 default:
2225 ret = 0;
2226 break;
2227 }
2228 return ret;
2229 }
2230
2231 #define WBD 0x781
2232 static int dib0090_tune(struct dvb_frontend *fe)
2233 {
2234 struct dib0090_state *state = fe->tuner_priv;
2235 const struct dib0090_tuning *tune = state->current_tune_table_index;
2236 const struct dib0090_pll *pll = state->current_pll_table_index;
2237 enum frontend_tune_state *tune_state = &state->tune_state;
2238
2239 u16 lo5, lo6, Den, tmp;
2240 u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
2241 int ret = 10;
2242 u8 c, i;
2243
2244
2245
2246
2247
2248
2249
2250 if (*tune_state == CT_TUNER_START) {
2251
2252 if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
2253 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
2254 else
2255
2256 if (state->config->analog_output == 0)
2257 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2258 }
2259
2260 if (state->calibrate & DC_CAL)
2261 return dib0090_dc_offset_calibration(state, tune_state);
2262 else if (state->calibrate & WBD_CAL) {
2263 if (state->current_rf == 0)
2264 state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
2265 return dib0090_wbd_calibration(state, tune_state);
2266 } else if (state->calibrate & TEMP_CAL)
2267 return dib0090_get_temperature(state, tune_state);
2268 else if (state->calibrate & CAPTRIM_CAL)
2269 return dib0090_captrim_search(state, tune_state);
2270
2271 if (*tune_state == CT_TUNER_START) {
2272
2273 if (state->config->use_pwm_agc && state->identity.in_soc) {
2274 tmp = dib0090_read_reg(state, 0x39);
2275 if ((tmp >> 10) & 0x1)
2276 dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
2277 }
2278
2279 state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
2280 state->rf_request =
2281 state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
2282 BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
2283 freq_offset_khz_vhf);
2284
2285
2286 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
2287 && state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
2288 const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
2289 u8 found_offset = 0;
2290 u32 margin_khz = 100;
2291
2292 if (LUT_offset != NULL) {
2293 while (LUT_offset->RF_freq != 0xffff) {
2294 if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
2295 && (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
2296 && LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
2297 state->rf_request += LUT_offset->offset_khz;
2298 found_offset = 1;
2299 break;
2300 }
2301 LUT_offset++;
2302 }
2303 }
2304
2305 if (found_offset == 0)
2306 state->rf_request += 400;
2307 }
2308 if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
2309 state->tuner_is_tuned = 0;
2310 state->current_rf = 0;
2311 state->current_standard = 0;
2312
2313 tune = dib0090_tuning_table;
2314 if (state->identity.p1g)
2315 tune = dib0090_p1g_tuning_table;
2316
2317 tmp = (state->identity.version >> 5) & 0x7;
2318
2319 if (state->identity.in_soc) {
2320 if (state->config->force_cband_input) {
2321 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
2322 || state->current_band & BAND_UHF) {
2323 state->current_band = BAND_CBAND;
2324 if (state->config->is_dib7090e)
2325 tune = dib0090_tuning_table_cband_7090e_sensitivity;
2326 else
2327 tune = dib0090_tuning_table_cband_7090;
2328 }
2329 } else {
2330 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
2331 state->current_band = BAND_CBAND;
2332 if (state->config->is_dib7090e)
2333 tune = dib0090_tuning_table_cband_7090e_sensitivity;
2334 else
2335 tune = dib0090_tuning_table_cband_7090;
2336 }
2337 }
2338 } else
2339 if (tmp == 0x4 || tmp == 0x7) {
2340
2341 if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
2342 state->current_band = BAND_CBAND;
2343
2344 tune = dib0090_tuning_table_fm_vhf_on_cband;
2345 if (state->identity.p1g)
2346 tune = dib0090_p1g_tuning_table_fm_vhf_on_cband;
2347 }
2348 }
2349
2350 pll = dib0090_pll_table;
2351 if (state->identity.p1g)
2352 pll = dib0090_p1g_pll_table;
2353
2354
2355 while (state->rf_request > tune->max_freq)
2356 tune++;
2357 while (state->rf_request > pll->max_freq)
2358 pll++;
2359
2360 state->current_tune_table_index = tune;
2361 state->current_pll_table_index = pll;
2362
2363 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
2364
2365 VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
2366
2367 FREF = state->config->io.clock_khz;
2368 if (state->config->fref_clock_ratio != 0)
2369 FREF /= state->config->fref_clock_ratio;
2370
2371 FBDiv = (VCOF_kHz / pll->topresc / FREF);
2372 Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
2373
2374 if (Rest < LPF)
2375 Rest = 0;
2376 else if (Rest < 2 * LPF)
2377 Rest = 2 * LPF;
2378 else if (Rest > (FREF - LPF)) {
2379 Rest = 0;
2380 FBDiv += 1;
2381 } else if (Rest > (FREF - 2 * LPF))
2382 Rest = FREF - 2 * LPF;
2383 Rest = (Rest * 6528) / (FREF / 10);
2384 state->rest = Rest;
2385
2386
2387
2388
2389
2390 if (Rest == 0) {
2391 if (pll->vco_band)
2392 lo5 = 0x049f;
2393 else
2394 lo5 = 0x041f;
2395 } else {
2396 if (pll->vco_band)
2397 lo5 = 0x049e;
2398 else if (state->config->analog_output)
2399 lo5 = 0x041d;
2400 else
2401 lo5 = 0x041c;
2402 }
2403
2404 if (state->identity.p1g) {
2405 if (state->identity.in_soc) {
2406 if (state->identity.version == SOC_8090_P1G_11R1)
2407 lo5 = 0x46f;
2408 else
2409 lo5 = 0x42f;
2410 } else
2411 lo5 = 0x42c;
2412 }
2413
2414 lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7);
2415
2416 if (!state->config->io.pll_int_loop_filt) {
2417 if (state->identity.in_soc)
2418 lo6 = 0xff98;
2419 else if (state->identity.p1g || (Rest == 0))
2420 lo6 = 0xfff8;
2421 else
2422 lo6 = 0xff28;
2423 } else
2424 lo6 = (state->config->io.pll_int_loop_filt << 3);
2425
2426 Den = 1;
2427
2428 if (Rest > 0) {
2429 lo6 |= (1 << 2) | 2;
2430 Den = 255;
2431 }
2432 dib0090_write_reg(state, 0x15, (u16) FBDiv);
2433 if (state->config->fref_clock_ratio != 0)
2434 dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
2435 else
2436 dib0090_write_reg(state, 0x16, (Den << 8) | 1);
2437 dib0090_write_reg(state, 0x17, (u16) Rest);
2438 dib0090_write_reg(state, 0x19, lo5);
2439 dib0090_write_reg(state, 0x1c, lo6);
2440
2441 lo6 = tune->tuner_enable;
2442 if (state->config->analog_output)
2443 lo6 = (lo6 & 0xff9f) | 0x2;
2444
2445 dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
2446
2447 }
2448
2449 state->current_rf = state->rf_request;
2450 state->current_standard = state->fe->dtv_property_cache.delivery_system;
2451
2452 ret = 20;
2453 state->calibrate = CAPTRIM_CAL;
2454 }
2455
2456 else if (*tune_state == CT_TUNER_STEP_0) {
2457 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
2458
2459 while (state->current_rf / 1000 > wbd->max_freq)
2460 wbd++;
2461
2462 dib0090_write_reg(state, 0x1e, 0x07ff);
2463 dprintk("Final Captrim: %d\n", (u32) state->fcaptrim);
2464 dprintk("HFDIV code: %d\n", (u32) pll->hfdiv_code);
2465 dprintk("VCO = %d\n", (u32) pll->vco_band);
2466 dprintk("VCOF in kHz: %d ((%d*%d) << 1))\n", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
2467 dprintk("REFDIV: %d, FREF: %d\n", (u32) 1, (u32) state->config->io.clock_khz);
2468 dprintk("FBDIV: %d, Rest: %d\n", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
2469 dprintk("Num: %d, Den: %d, SD: %d\n", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
2470 (u32) dib0090_read_reg(state, 0x1c) & 0x3);
2471
2472 #define WBD 0x781
2473 c = 4;
2474 i = 3;
2475
2476 if (wbd->wbd_gain != 0)
2477 c = wbd->wbd_gain;
2478
2479 state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
2480 dib0090_write_reg(state, 0x10, state->wbdmux);
2481
2482 if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
2483 dprintk("P1G : The cable band is selected and lna_tune = %d\n", tune->lna_tune);
2484 dib0090_write_reg(state, 0x09, tune->lna_bias);
2485 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
2486 } else
2487 dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
2488
2489 dib0090_write_reg(state, 0x0c, tune->v2i);
2490 dib0090_write_reg(state, 0x0d, tune->mix);
2491 dib0090_write_reg(state, 0x0e, tune->load);
2492 *tune_state = CT_TUNER_STEP_1;
2493
2494 } else if (*tune_state == CT_TUNER_STEP_1) {
2495
2496 state->rf_lt_def = 0x7c00;
2497
2498 dib0090_set_bandwidth(state);
2499 state->tuner_is_tuned = 1;
2500
2501 state->calibrate |= WBD_CAL;
2502 state->calibrate |= TEMP_CAL;
2503 *tune_state = CT_TUNER_STOP;
2504 } else
2505 ret = FE_CALLBACK_TIME_NEVER;
2506 return ret;
2507 }
2508
2509 static void dib0090_release(struct dvb_frontend *fe)
2510 {
2511 kfree(fe->tuner_priv);
2512 fe->tuner_priv = NULL;
2513 }
2514
2515 enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
2516 {
2517 struct dib0090_state *state = fe->tuner_priv;
2518
2519 return state->tune_state;
2520 }
2521
2522 EXPORT_SYMBOL(dib0090_get_tune_state);
2523
2524 int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2525 {
2526 struct dib0090_state *state = fe->tuner_priv;
2527
2528 state->tune_state = tune_state;
2529 return 0;
2530 }
2531
2532 EXPORT_SYMBOL(dib0090_set_tune_state);
2533
2534 static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
2535 {
2536 struct dib0090_state *state = fe->tuner_priv;
2537
2538 *frequency = 1000 * state->current_rf;
2539 return 0;
2540 }
2541
2542 static int dib0090_set_params(struct dvb_frontend *fe)
2543 {
2544 struct dib0090_state *state = fe->tuner_priv;
2545 u32 ret;
2546
2547 state->tune_state = CT_TUNER_START;
2548
2549 do {
2550 ret = dib0090_tune(fe);
2551 if (ret == FE_CALLBACK_TIME_NEVER)
2552 break;
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562 ret = 10 * (ret + 99)/100;
2563 usleep_range(ret * 1000, (ret + 1) * 1000);
2564 } while (state->tune_state != CT_TUNER_STOP);
2565
2566 return 0;
2567 }
2568
2569 static const struct dvb_tuner_ops dib0090_ops = {
2570 .info = {
2571 .name = "DiBcom DiB0090",
2572 .frequency_min_hz = 45 * MHz,
2573 .frequency_max_hz = 860 * MHz,
2574 .frequency_step_hz = 1 * kHz,
2575 },
2576 .release = dib0090_release,
2577
2578 .init = dib0090_wakeup,
2579 .sleep = dib0090_sleep,
2580 .set_params = dib0090_set_params,
2581 .get_frequency = dib0090_get_frequency,
2582 };
2583
2584 static const struct dvb_tuner_ops dib0090_fw_ops = {
2585 .info = {
2586 .name = "DiBcom DiB0090",
2587 .frequency_min_hz = 45 * MHz,
2588 .frequency_max_hz = 860 * MHz,
2589 .frequency_step_hz = 1 * kHz,
2590 },
2591 .release = dib0090_release,
2592
2593 .init = NULL,
2594 .sleep = NULL,
2595 .set_params = NULL,
2596 .get_frequency = NULL,
2597 };
2598
2599 static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = {
2600 {470, 0, 250, 0, 100, 4},
2601 {860, 51, 866, 21, 375, 4},
2602 {1700, 0, 800, 0, 850, 4},
2603 {2900, 0, 250, 0, 100, 6},
2604 {0xFFFF, 0, 0, 0, 0, 0},
2605 };
2606
2607 struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2608 {
2609 struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
2610 if (st == NULL)
2611 return NULL;
2612
2613 st->config = config;
2614 st->i2c = i2c;
2615 st->fe = fe;
2616 mutex_init(&st->i2c_buffer_lock);
2617 fe->tuner_priv = st;
2618
2619 if (config->wbd == NULL)
2620 st->current_wbd_table = dib0090_wbd_table_default;
2621 else
2622 st->current_wbd_table = config->wbd;
2623
2624 if (dib0090_reset(fe) != 0)
2625 goto free_mem;
2626
2627 pr_info("DiB0090: successfully identified\n");
2628 memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
2629
2630 return fe;
2631 free_mem:
2632 kfree(st);
2633 fe->tuner_priv = NULL;
2634 return NULL;
2635 }
2636
2637 EXPORT_SYMBOL(dib0090_register);
2638
2639 struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2640 {
2641 struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL);
2642 if (st == NULL)
2643 return NULL;
2644
2645 st->config = config;
2646 st->i2c = i2c;
2647 st->fe = fe;
2648 mutex_init(&st->i2c_buffer_lock);
2649 fe->tuner_priv = st;
2650
2651 if (dib0090_fw_reset_digital(fe, st->config) != 0)
2652 goto free_mem;
2653
2654 dprintk("DiB0090 FW: successfully identified\n");
2655 memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops));
2656
2657 return fe;
2658 free_mem:
2659 kfree(st);
2660 fe->tuner_priv = NULL;
2661 return NULL;
2662 }
2663 EXPORT_SYMBOL(dib0090_fw_register);
2664
2665 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
2666 MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>");
2667 MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
2668 MODULE_LICENSE("GPL");