0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "fc0013.h"
0011 #include "fc0013-priv.h"
0012
0013 static int fc0013_writereg(struct fc0013_priv *priv, u8 reg, u8 val)
0014 {
0015 u8 buf[2] = {reg, val};
0016 struct i2c_msg msg = {
0017 .addr = priv->addr, .flags = 0, .buf = buf, .len = 2
0018 };
0019
0020 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
0021 err("I2C write reg failed, reg: %02x, val: %02x", reg, val);
0022 return -EREMOTEIO;
0023 }
0024 return 0;
0025 }
0026
0027 static int fc0013_readreg(struct fc0013_priv *priv, u8 reg, u8 *val)
0028 {
0029 struct i2c_msg msg[2] = {
0030 { .addr = priv->addr, .flags = 0, .buf = ®, .len = 1 },
0031 { .addr = priv->addr, .flags = I2C_M_RD, .buf = val, .len = 1 },
0032 };
0033
0034 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
0035 err("I2C read reg failed, reg: %02x", reg);
0036 return -EREMOTEIO;
0037 }
0038 return 0;
0039 }
0040
0041 static void fc0013_release(struct dvb_frontend *fe)
0042 {
0043 kfree(fe->tuner_priv);
0044 fe->tuner_priv = NULL;
0045 }
0046
0047 static int fc0013_init(struct dvb_frontend *fe)
0048 {
0049 struct fc0013_priv *priv = fe->tuner_priv;
0050 int i, ret = 0;
0051 unsigned char reg[] = {
0052 0x00,
0053 0x09,
0054 0x16,
0055 0x00,
0056 0x00,
0057 0x17,
0058 0x02,
0059 0x0a,
0060 0xff,
0061
0062 0x6f,
0063 0xb8,
0064 0x82,
0065 0xfc,
0066 0x01,
0067 0x00,
0068 0x00,
0069 0x00,
0070 0x00,
0071 0x00,
0072 0x00,
0073 0x50,
0074
0075 0x01,
0076 };
0077
0078 switch (priv->xtal_freq) {
0079 case FC_XTAL_27_MHZ:
0080 case FC_XTAL_28_8_MHZ:
0081 reg[0x07] |= 0x20;
0082 break;
0083 case FC_XTAL_36_MHZ:
0084 default:
0085 break;
0086 }
0087
0088 if (priv->dual_master)
0089 reg[0x0c] |= 0x02;
0090
0091 if (fe->ops.i2c_gate_ctrl)
0092 fe->ops.i2c_gate_ctrl(fe, 1);
0093
0094 for (i = 1; i < sizeof(reg); i++) {
0095 ret = fc0013_writereg(priv, i, reg[i]);
0096 if (ret)
0097 break;
0098 }
0099
0100 if (fe->ops.i2c_gate_ctrl)
0101 fe->ops.i2c_gate_ctrl(fe, 0);
0102
0103 if (ret)
0104 err("fc0013_writereg failed: %d", ret);
0105
0106 return ret;
0107 }
0108
0109 static int fc0013_sleep(struct dvb_frontend *fe)
0110 {
0111
0112 return 0;
0113 }
0114
0115 int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val)
0116 {
0117 struct fc0013_priv *priv = fe->tuner_priv;
0118 int ret;
0119 u8 rc_cal;
0120 int val;
0121
0122 if (fe->ops.i2c_gate_ctrl)
0123 fe->ops.i2c_gate_ctrl(fe, 1);
0124
0125
0126 ret = fc0013_writereg(priv, 0x10, 0x00);
0127 if (ret)
0128 goto error_out;
0129
0130
0131 ret = fc0013_readreg(priv, 0x10, &rc_cal);
0132 if (ret)
0133 goto error_out;
0134
0135 rc_cal &= 0x0f;
0136
0137 val = (int)rc_cal + rc_val;
0138
0139
0140 ret = fc0013_writereg(priv, 0x0d, 0x11);
0141 if (ret)
0142 goto error_out;
0143
0144
0145 if (val > 15)
0146 ret = fc0013_writereg(priv, 0x10, 0x0f);
0147 else if (val < 0)
0148 ret = fc0013_writereg(priv, 0x10, 0x00);
0149 else
0150 ret = fc0013_writereg(priv, 0x10, (u8)val);
0151
0152 error_out:
0153 if (fe->ops.i2c_gate_ctrl)
0154 fe->ops.i2c_gate_ctrl(fe, 0);
0155
0156 return ret;
0157 }
0158 EXPORT_SYMBOL(fc0013_rc_cal_add);
0159
0160 int fc0013_rc_cal_reset(struct dvb_frontend *fe)
0161 {
0162 struct fc0013_priv *priv = fe->tuner_priv;
0163 int ret;
0164
0165 if (fe->ops.i2c_gate_ctrl)
0166 fe->ops.i2c_gate_ctrl(fe, 1);
0167
0168 ret = fc0013_writereg(priv, 0x0d, 0x01);
0169 if (!ret)
0170 ret = fc0013_writereg(priv, 0x10, 0x00);
0171
0172 if (fe->ops.i2c_gate_ctrl)
0173 fe->ops.i2c_gate_ctrl(fe, 0);
0174
0175 return ret;
0176 }
0177 EXPORT_SYMBOL(fc0013_rc_cal_reset);
0178
0179 static int fc0013_set_vhf_track(struct fc0013_priv *priv, u32 freq)
0180 {
0181 int ret;
0182 u8 tmp;
0183
0184 ret = fc0013_readreg(priv, 0x1d, &tmp);
0185 if (ret)
0186 goto error_out;
0187 tmp &= 0xe3;
0188 if (freq <= 177500) {
0189 ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
0190 } else if (freq <= 184500) {
0191 ret = fc0013_writereg(priv, 0x1d, tmp | 0x18);
0192 } else if (freq <= 191500) {
0193 ret = fc0013_writereg(priv, 0x1d, tmp | 0x14);
0194 } else if (freq <= 198500) {
0195 ret = fc0013_writereg(priv, 0x1d, tmp | 0x10);
0196 } else if (freq <= 205500) {
0197 ret = fc0013_writereg(priv, 0x1d, tmp | 0x0c);
0198 } else if (freq <= 219500) {
0199 ret = fc0013_writereg(priv, 0x1d, tmp | 0x08);
0200 } else if (freq < 300000) {
0201 ret = fc0013_writereg(priv, 0x1d, tmp | 0x04);
0202 } else {
0203 ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
0204 }
0205 error_out:
0206 return ret;
0207 }
0208
0209 static int fc0013_set_params(struct dvb_frontend *fe)
0210 {
0211 struct fc0013_priv *priv = fe->tuner_priv;
0212 int i, ret = 0;
0213 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0214 u32 freq = p->frequency / 1000;
0215 u32 delsys = p->delivery_system;
0216 unsigned char reg[7], am, pm, multi, tmp;
0217 unsigned long f_vco;
0218 unsigned short xtal_freq_khz_2, xin, xdiv;
0219 bool vco_select = false;
0220
0221 if (fe->callback) {
0222 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
0223 FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
0224 if (ret)
0225 goto exit;
0226 }
0227
0228 switch (priv->xtal_freq) {
0229 case FC_XTAL_27_MHZ:
0230 xtal_freq_khz_2 = 27000 / 2;
0231 break;
0232 case FC_XTAL_36_MHZ:
0233 xtal_freq_khz_2 = 36000 / 2;
0234 break;
0235 case FC_XTAL_28_8_MHZ:
0236 default:
0237 xtal_freq_khz_2 = 28800 / 2;
0238 break;
0239 }
0240
0241 if (fe->ops.i2c_gate_ctrl)
0242 fe->ops.i2c_gate_ctrl(fe, 1);
0243
0244
0245 ret = fc0013_set_vhf_track(priv, freq);
0246 if (ret)
0247 goto exit;
0248
0249 if (freq < 300000) {
0250
0251 ret = fc0013_readreg(priv, 0x07, &tmp);
0252 if (ret)
0253 goto exit;
0254 ret = fc0013_writereg(priv, 0x07, tmp | 0x10);
0255 if (ret)
0256 goto exit;
0257
0258
0259 ret = fc0013_readreg(priv, 0x14, &tmp);
0260 if (ret)
0261 goto exit;
0262 ret = fc0013_writereg(priv, 0x14, tmp & 0x1f);
0263 if (ret)
0264 goto exit;
0265 } else if (freq <= 862000) {
0266
0267 ret = fc0013_readreg(priv, 0x07, &tmp);
0268 if (ret)
0269 goto exit;
0270 ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
0271 if (ret)
0272 goto exit;
0273
0274
0275 ret = fc0013_readreg(priv, 0x14, &tmp);
0276 if (ret)
0277 goto exit;
0278 ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x40);
0279 if (ret)
0280 goto exit;
0281 } else {
0282
0283 ret = fc0013_readreg(priv, 0x07, &tmp);
0284 if (ret)
0285 goto exit;
0286 ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
0287 if (ret)
0288 goto exit;
0289
0290
0291 ret = fc0013_readreg(priv, 0x14, &tmp);
0292 if (ret)
0293 goto exit;
0294 ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x20);
0295 if (ret)
0296 goto exit;
0297 }
0298
0299
0300 if (freq < 37084) {
0301 multi = 96;
0302 reg[5] = 0x82;
0303 reg[6] = 0x00;
0304 } else if (freq < 55625) {
0305 multi = 64;
0306 reg[5] = 0x02;
0307 reg[6] = 0x02;
0308 } else if (freq < 74167) {
0309 multi = 48;
0310 reg[5] = 0x42;
0311 reg[6] = 0x00;
0312 } else if (freq < 111250) {
0313 multi = 32;
0314 reg[5] = 0x82;
0315 reg[6] = 0x02;
0316 } else if (freq < 148334) {
0317 multi = 24;
0318 reg[5] = 0x22;
0319 reg[6] = 0x00;
0320 } else if (freq < 222500) {
0321 multi = 16;
0322 reg[5] = 0x42;
0323 reg[6] = 0x02;
0324 } else if (freq < 296667) {
0325 multi = 12;
0326 reg[5] = 0x12;
0327 reg[6] = 0x00;
0328 } else if (freq < 445000) {
0329 multi = 8;
0330 reg[5] = 0x22;
0331 reg[6] = 0x02;
0332 } else if (freq < 593334) {
0333 multi = 6;
0334 reg[5] = 0x0a;
0335 reg[6] = 0x00;
0336 } else if (freq < 950000) {
0337 multi = 4;
0338 reg[5] = 0x12;
0339 reg[6] = 0x02;
0340 } else {
0341 multi = 2;
0342 reg[5] = 0x0a;
0343 reg[6] = 0x02;
0344 }
0345
0346 f_vco = freq * multi;
0347
0348 if (f_vco >= 3060000) {
0349 reg[6] |= 0x08;
0350 vco_select = true;
0351 }
0352
0353 if (freq >= 45000) {
0354
0355 xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
0356 if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
0357 xdiv++;
0358
0359 pm = (unsigned char)(xdiv / 8);
0360 am = (unsigned char)(xdiv - (8 * pm));
0361
0362 if (am < 2) {
0363 reg[1] = am + 8;
0364 reg[2] = pm - 1;
0365 } else {
0366 reg[1] = am;
0367 reg[2] = pm;
0368 }
0369 } else {
0370
0371 reg[1] = 0x06;
0372 reg[2] = 0x11;
0373 }
0374
0375
0376 reg[6] |= 0x20;
0377
0378
0379
0380 xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
0381 xin = (xin << 15) / xtal_freq_khz_2;
0382 if (xin >= 16384)
0383 xin += 32768;
0384
0385 reg[3] = xin >> 8;
0386 reg[4] = xin & 0xff;
0387
0388 if (delsys == SYS_DVBT) {
0389 reg[6] &= 0x3f;
0390 switch (p->bandwidth_hz) {
0391 case 6000000:
0392 reg[6] |= 0x80;
0393 break;
0394 case 7000000:
0395 reg[6] |= 0x40;
0396 break;
0397 case 8000000:
0398 default:
0399 break;
0400 }
0401 } else {
0402 err("%s: modulation type not supported!", __func__);
0403 return -EINVAL;
0404 }
0405
0406
0407 reg[5] |= 0x07;
0408
0409 for (i = 1; i <= 6; i++) {
0410 ret = fc0013_writereg(priv, i, reg[i]);
0411 if (ret)
0412 goto exit;
0413 }
0414
0415 ret = fc0013_readreg(priv, 0x11, &tmp);
0416 if (ret)
0417 goto exit;
0418 if (multi == 64)
0419 ret = fc0013_writereg(priv, 0x11, tmp | 0x04);
0420 else
0421 ret = fc0013_writereg(priv, 0x11, tmp & 0xfb);
0422 if (ret)
0423 goto exit;
0424
0425
0426 ret = fc0013_writereg(priv, 0x0e, 0x80);
0427 if (!ret)
0428 ret = fc0013_writereg(priv, 0x0e, 0x00);
0429
0430
0431 if (!ret)
0432 ret = fc0013_writereg(priv, 0x0e, 0x00);
0433
0434 if (!ret) {
0435 msleep(10);
0436 ret = fc0013_readreg(priv, 0x0e, &tmp);
0437 }
0438 if (ret)
0439 goto exit;
0440
0441
0442 tmp &= 0x3f;
0443
0444 if (vco_select) {
0445 if (tmp > 0x3c) {
0446 reg[6] &= ~0x08;
0447 ret = fc0013_writereg(priv, 0x06, reg[6]);
0448 if (!ret)
0449 ret = fc0013_writereg(priv, 0x0e, 0x80);
0450 if (!ret)
0451 ret = fc0013_writereg(priv, 0x0e, 0x00);
0452 }
0453 } else {
0454 if (tmp < 0x02) {
0455 reg[6] |= 0x08;
0456 ret = fc0013_writereg(priv, 0x06, reg[6]);
0457 if (!ret)
0458 ret = fc0013_writereg(priv, 0x0e, 0x80);
0459 if (!ret)
0460 ret = fc0013_writereg(priv, 0x0e, 0x00);
0461 }
0462 }
0463
0464 priv->frequency = p->frequency;
0465 priv->bandwidth = p->bandwidth_hz;
0466
0467 exit:
0468 if (fe->ops.i2c_gate_ctrl)
0469 fe->ops.i2c_gate_ctrl(fe, 0);
0470 if (ret)
0471 warn("%s: failed: %d", __func__, ret);
0472 return ret;
0473 }
0474
0475 static int fc0013_get_frequency(struct dvb_frontend *fe, u32 *frequency)
0476 {
0477 struct fc0013_priv *priv = fe->tuner_priv;
0478 *frequency = priv->frequency;
0479 return 0;
0480 }
0481
0482 static int fc0013_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
0483 {
0484
0485 *frequency = 0;
0486 return 0;
0487 }
0488
0489 static int fc0013_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
0490 {
0491 struct fc0013_priv *priv = fe->tuner_priv;
0492 *bandwidth = priv->bandwidth;
0493 return 0;
0494 }
0495
0496 #define INPUT_ADC_LEVEL -8
0497
0498 static int fc0013_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
0499 {
0500 struct fc0013_priv *priv = fe->tuner_priv;
0501 int ret;
0502 unsigned char tmp;
0503 int int_temp, lna_gain, int_lna, tot_agc_gain, power;
0504 static const int fc0013_lna_gain_table[] = {
0505
0506 -63, -58, -99, -73,
0507 -63, -65, -54, -60,
0508
0509 71, 70, 68, 67,
0510 65, 63, 61, 58,
0511
0512 197, 191, 188, 186,
0513 184, 182, 181, 179,
0514 };
0515
0516 if (fe->ops.i2c_gate_ctrl)
0517 fe->ops.i2c_gate_ctrl(fe, 1);
0518
0519 ret = fc0013_writereg(priv, 0x13, 0x00);
0520 if (ret)
0521 goto err;
0522
0523 ret = fc0013_readreg(priv, 0x13, &tmp);
0524 if (ret)
0525 goto err;
0526 int_temp = tmp;
0527
0528 ret = fc0013_readreg(priv, 0x14, &tmp);
0529 if (ret)
0530 goto err;
0531 lna_gain = tmp & 0x1f;
0532
0533 if (fe->ops.i2c_gate_ctrl)
0534 fe->ops.i2c_gate_ctrl(fe, 0);
0535
0536 if (lna_gain < ARRAY_SIZE(fc0013_lna_gain_table)) {
0537 int_lna = fc0013_lna_gain_table[lna_gain];
0538 tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
0539 (int_temp & 0x1f)) * 2;
0540 power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
0541
0542 if (power >= 45)
0543 *strength = 255;
0544 else if (power < -95)
0545 *strength = 0;
0546 else
0547 *strength = (power + 95) * 255 / 140;
0548
0549 *strength |= *strength << 8;
0550 } else {
0551 ret = -1;
0552 }
0553
0554 goto exit;
0555
0556 err:
0557 if (fe->ops.i2c_gate_ctrl)
0558 fe->ops.i2c_gate_ctrl(fe, 0);
0559 exit:
0560 if (ret)
0561 warn("%s: failed: %d", __func__, ret);
0562 return ret;
0563 }
0564
0565 static const struct dvb_tuner_ops fc0013_tuner_ops = {
0566 .info = {
0567 .name = "Fitipower FC0013",
0568
0569 .frequency_min_hz = 37 * MHz,
0570 .frequency_max_hz = 1680 * MHz,
0571 },
0572
0573 .release = fc0013_release,
0574
0575 .init = fc0013_init,
0576 .sleep = fc0013_sleep,
0577
0578 .set_params = fc0013_set_params,
0579
0580 .get_frequency = fc0013_get_frequency,
0581 .get_if_frequency = fc0013_get_if_frequency,
0582 .get_bandwidth = fc0013_get_bandwidth,
0583
0584 .get_rf_strength = fc0013_get_rf_strength,
0585 };
0586
0587 struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
0588 struct i2c_adapter *i2c, u8 i2c_address, int dual_master,
0589 enum fc001x_xtal_freq xtal_freq)
0590 {
0591 struct fc0013_priv *priv = NULL;
0592
0593 priv = kzalloc(sizeof(struct fc0013_priv), GFP_KERNEL);
0594 if (priv == NULL)
0595 return NULL;
0596
0597 priv->i2c = i2c;
0598 priv->dual_master = dual_master;
0599 priv->addr = i2c_address;
0600 priv->xtal_freq = xtal_freq;
0601
0602 info("Fitipower FC0013 successfully attached.");
0603
0604 fe->tuner_priv = priv;
0605
0606 memcpy(&fe->ops.tuner_ops, &fc0013_tuner_ops,
0607 sizeof(struct dvb_tuner_ops));
0608
0609 return fe;
0610 }
0611 EXPORT_SYMBOL(fc0013_attach);
0612
0613 MODULE_DESCRIPTION("Fitipower FC0013 silicon tuner driver");
0614 MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
0615 MODULE_LICENSE("GPL");
0616 MODULE_VERSION("0.2");