0001
0002
0003
0004
0005
0006
0007
0008 #include "fc0012.h"
0009 #include "fc0012-priv.h"
0010
0011 static int fc0012_writereg(struct fc0012_priv *priv, u8 reg, u8 val)
0012 {
0013 u8 buf[2] = {reg, val};
0014 struct i2c_msg msg = {
0015 .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
0016 };
0017
0018 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
0019 dev_err(&priv->i2c->dev,
0020 "%s: I2C write reg failed, reg: %02x, val: %02x\n",
0021 KBUILD_MODNAME, reg, val);
0022 return -EREMOTEIO;
0023 }
0024 return 0;
0025 }
0026
0027 static int fc0012_readreg(struct fc0012_priv *priv, u8 reg, u8 *val)
0028 {
0029 struct i2c_msg msg[2] = {
0030 { .addr = priv->cfg->i2c_address, .flags = 0,
0031 .buf = ®, .len = 1 },
0032 { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
0033 .buf = val, .len = 1 },
0034 };
0035
0036 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
0037 dev_err(&priv->i2c->dev,
0038 "%s: I2C read reg failed, reg: %02x\n",
0039 KBUILD_MODNAME, reg);
0040 return -EREMOTEIO;
0041 }
0042 return 0;
0043 }
0044
0045 static void fc0012_release(struct dvb_frontend *fe)
0046 {
0047 kfree(fe->tuner_priv);
0048 fe->tuner_priv = NULL;
0049 }
0050
0051 static int fc0012_init(struct dvb_frontend *fe)
0052 {
0053 struct fc0012_priv *priv = fe->tuner_priv;
0054 int i, ret = 0;
0055 unsigned char reg[] = {
0056 0x00,
0057 0x05,
0058 0x10,
0059 0x00,
0060 0x00,
0061 0x0f,
0062 0x00,
0063 0x00,
0064 0xff,
0065
0066 0x6e,
0067 0xb8,
0068 0x82,
0069
0070 0xfc,
0071 0x02,
0072 0x00,
0073 0x00,
0074 0x00,
0075 0x00,
0076 0x1f,
0077 0x08,
0078
0079 0x00,
0080 0x04,
0081 };
0082
0083 switch (priv->cfg->xtal_freq) {
0084 case FC_XTAL_27_MHZ:
0085 case FC_XTAL_28_8_MHZ:
0086 reg[0x07] |= 0x20;
0087 break;
0088 case FC_XTAL_36_MHZ:
0089 default:
0090 break;
0091 }
0092
0093 if (priv->cfg->dual_master)
0094 reg[0x0c] |= 0x02;
0095
0096 if (priv->cfg->loop_through)
0097 reg[0x09] |= 0x01;
0098
0099 if (fe->ops.i2c_gate_ctrl)
0100 fe->ops.i2c_gate_ctrl(fe, 1);
0101
0102 for (i = 1; i < sizeof(reg); i++) {
0103 ret = fc0012_writereg(priv, i, reg[i]);
0104 if (ret)
0105 break;
0106 }
0107
0108 if (fe->ops.i2c_gate_ctrl)
0109 fe->ops.i2c_gate_ctrl(fe, 0);
0110
0111 if (ret)
0112 dev_err(&priv->i2c->dev, "%s: fc0012_writereg failed: %d\n",
0113 KBUILD_MODNAME, ret);
0114
0115 return ret;
0116 }
0117
0118 static int fc0012_set_params(struct dvb_frontend *fe)
0119 {
0120 struct fc0012_priv *priv = fe->tuner_priv;
0121 int i, ret = 0;
0122 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0123 u32 freq = p->frequency / 1000;
0124 u32 delsys = p->delivery_system;
0125 unsigned char reg[7], am, pm, multi, tmp;
0126 unsigned long f_vco;
0127 unsigned short xtal_freq_khz_2, xin, xdiv;
0128 bool vco_select = false;
0129
0130 if (fe->callback) {
0131 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
0132 FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
0133 if (ret)
0134 goto exit;
0135 }
0136
0137 switch (priv->cfg->xtal_freq) {
0138 case FC_XTAL_27_MHZ:
0139 xtal_freq_khz_2 = 27000 / 2;
0140 break;
0141 case FC_XTAL_36_MHZ:
0142 xtal_freq_khz_2 = 36000 / 2;
0143 break;
0144 case FC_XTAL_28_8_MHZ:
0145 default:
0146 xtal_freq_khz_2 = 28800 / 2;
0147 break;
0148 }
0149
0150
0151 if (freq < 37084) {
0152 multi = 96;
0153 reg[5] = 0x82;
0154 reg[6] = 0x00;
0155 } else if (freq < 55625) {
0156 multi = 64;
0157 reg[5] = 0x82;
0158 reg[6] = 0x02;
0159 } else if (freq < 74167) {
0160 multi = 48;
0161 reg[5] = 0x42;
0162 reg[6] = 0x00;
0163 } else if (freq < 111250) {
0164 multi = 32;
0165 reg[5] = 0x42;
0166 reg[6] = 0x02;
0167 } else if (freq < 148334) {
0168 multi = 24;
0169 reg[5] = 0x22;
0170 reg[6] = 0x00;
0171 } else if (freq < 222500) {
0172 multi = 16;
0173 reg[5] = 0x22;
0174 reg[6] = 0x02;
0175 } else if (freq < 296667) {
0176 multi = 12;
0177 reg[5] = 0x12;
0178 reg[6] = 0x00;
0179 } else if (freq < 445000) {
0180 multi = 8;
0181 reg[5] = 0x12;
0182 reg[6] = 0x02;
0183 } else if (freq < 593334) {
0184 multi = 6;
0185 reg[5] = 0x0a;
0186 reg[6] = 0x00;
0187 } else {
0188 multi = 4;
0189 reg[5] = 0x0a;
0190 reg[6] = 0x02;
0191 }
0192
0193 f_vco = freq * multi;
0194
0195 if (f_vco >= 3060000) {
0196 reg[6] |= 0x08;
0197 vco_select = true;
0198 }
0199
0200 if (freq >= 45000) {
0201
0202 xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
0203 if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
0204 xdiv++;
0205
0206 pm = (unsigned char)(xdiv / 8);
0207 am = (unsigned char)(xdiv - (8 * pm));
0208
0209 if (am < 2) {
0210 reg[1] = am + 8;
0211 reg[2] = pm - 1;
0212 } else {
0213 reg[1] = am;
0214 reg[2] = pm;
0215 }
0216 } else {
0217
0218 reg[1] = 0x06;
0219 reg[2] = 0x11;
0220 }
0221
0222
0223 reg[6] |= 0x20;
0224
0225
0226
0227 xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
0228 xin = (xin << 15) / xtal_freq_khz_2;
0229 if (xin >= 16384)
0230 xin += 32768;
0231
0232 reg[3] = xin >> 8;
0233 reg[4] = xin & 0xff;
0234
0235 if (delsys == SYS_DVBT) {
0236 reg[6] &= 0x3f;
0237 switch (p->bandwidth_hz) {
0238 case 6000000:
0239 reg[6] |= 0x80;
0240 break;
0241 case 7000000:
0242 reg[6] |= 0x40;
0243 break;
0244 case 8000000:
0245 default:
0246 break;
0247 }
0248 } else {
0249 dev_err(&priv->i2c->dev, "%s: modulation type not supported!\n",
0250 KBUILD_MODNAME);
0251 return -EINVAL;
0252 }
0253
0254
0255 reg[5] |= 0x07;
0256
0257 if (fe->ops.i2c_gate_ctrl)
0258 fe->ops.i2c_gate_ctrl(fe, 1);
0259
0260 for (i = 1; i <= 6; i++) {
0261 ret = fc0012_writereg(priv, i, reg[i]);
0262 if (ret)
0263 goto exit;
0264 }
0265
0266
0267 ret = fc0012_writereg(priv, 0x0e, 0x80);
0268 if (!ret)
0269 ret = fc0012_writereg(priv, 0x0e, 0x00);
0270
0271
0272 if (!ret)
0273 ret = fc0012_writereg(priv, 0x0e, 0x00);
0274
0275 if (!ret) {
0276 msleep(10);
0277 ret = fc0012_readreg(priv, 0x0e, &tmp);
0278 }
0279 if (ret)
0280 goto exit;
0281
0282
0283 tmp &= 0x3f;
0284
0285 if (vco_select) {
0286 if (tmp > 0x3c) {
0287 reg[6] &= ~0x08;
0288 ret = fc0012_writereg(priv, 0x06, reg[6]);
0289 if (!ret)
0290 ret = fc0012_writereg(priv, 0x0e, 0x80);
0291 if (!ret)
0292 ret = fc0012_writereg(priv, 0x0e, 0x00);
0293 }
0294 } else {
0295 if (tmp < 0x02) {
0296 reg[6] |= 0x08;
0297 ret = fc0012_writereg(priv, 0x06, reg[6]);
0298 if (!ret)
0299 ret = fc0012_writereg(priv, 0x0e, 0x80);
0300 if (!ret)
0301 ret = fc0012_writereg(priv, 0x0e, 0x00);
0302 }
0303 }
0304
0305 priv->frequency = p->frequency;
0306 priv->bandwidth = p->bandwidth_hz;
0307
0308 exit:
0309 if (fe->ops.i2c_gate_ctrl)
0310 fe->ops.i2c_gate_ctrl(fe, 0);
0311 if (ret)
0312 dev_warn(&priv->i2c->dev, "%s: %s failed: %d\n",
0313 KBUILD_MODNAME, __func__, ret);
0314 return ret;
0315 }
0316
0317 static int fc0012_get_frequency(struct dvb_frontend *fe, u32 *frequency)
0318 {
0319 struct fc0012_priv *priv = fe->tuner_priv;
0320 *frequency = priv->frequency;
0321 return 0;
0322 }
0323
0324 static int fc0012_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
0325 {
0326 *frequency = 0;
0327 return 0;
0328 }
0329
0330 static int fc0012_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
0331 {
0332 struct fc0012_priv *priv = fe->tuner_priv;
0333 *bandwidth = priv->bandwidth;
0334 return 0;
0335 }
0336
0337 #define INPUT_ADC_LEVEL -8
0338
0339 static int fc0012_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
0340 {
0341 struct fc0012_priv *priv = fe->tuner_priv;
0342 int ret;
0343 unsigned char tmp;
0344 int int_temp, lna_gain, int_lna, tot_agc_gain, power;
0345 static const int fc0012_lna_gain_table[] = {
0346
0347 -63, -58, -99, -73,
0348 -63, -65, -54, -60,
0349
0350 71, 70, 68, 67,
0351 65, 63, 61, 58,
0352
0353 197, 191, 188, 186,
0354 184, 182, 181, 179,
0355 };
0356
0357 if (fe->ops.i2c_gate_ctrl)
0358 fe->ops.i2c_gate_ctrl(fe, 1);
0359
0360 ret = fc0012_writereg(priv, 0x12, 0x00);
0361 if (ret)
0362 goto err;
0363
0364 ret = fc0012_readreg(priv, 0x12, &tmp);
0365 if (ret)
0366 goto err;
0367 int_temp = tmp;
0368
0369 ret = fc0012_readreg(priv, 0x13, &tmp);
0370 if (ret)
0371 goto err;
0372 lna_gain = tmp & 0x1f;
0373
0374 if (fe->ops.i2c_gate_ctrl)
0375 fe->ops.i2c_gate_ctrl(fe, 0);
0376
0377 if (lna_gain < ARRAY_SIZE(fc0012_lna_gain_table)) {
0378 int_lna = fc0012_lna_gain_table[lna_gain];
0379 tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
0380 (int_temp & 0x1f)) * 2;
0381 power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
0382
0383 if (power >= 45)
0384 *strength = 255;
0385 else if (power < -95)
0386 *strength = 0;
0387 else
0388 *strength = (power + 95) * 255 / 140;
0389
0390 *strength |= *strength << 8;
0391 } else {
0392 ret = -1;
0393 }
0394
0395 goto exit;
0396
0397 err:
0398 if (fe->ops.i2c_gate_ctrl)
0399 fe->ops.i2c_gate_ctrl(fe, 0);
0400 exit:
0401 if (ret)
0402 dev_warn(&priv->i2c->dev, "%s: %s failed: %d\n",
0403 KBUILD_MODNAME, __func__, ret);
0404 return ret;
0405 }
0406
0407 static const struct dvb_tuner_ops fc0012_tuner_ops = {
0408 .info = {
0409 .name = "Fitipower FC0012",
0410
0411 .frequency_min_hz = 37 * MHz,
0412 .frequency_max_hz = 862 * MHz,
0413 },
0414
0415 .release = fc0012_release,
0416
0417 .init = fc0012_init,
0418
0419 .set_params = fc0012_set_params,
0420
0421 .get_frequency = fc0012_get_frequency,
0422 .get_if_frequency = fc0012_get_if_frequency,
0423 .get_bandwidth = fc0012_get_bandwidth,
0424
0425 .get_rf_strength = fc0012_get_rf_strength,
0426 };
0427
0428 struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
0429 struct i2c_adapter *i2c, const struct fc0012_config *cfg)
0430 {
0431 struct fc0012_priv *priv;
0432 int ret;
0433 u8 chip_id;
0434
0435 if (fe->ops.i2c_gate_ctrl)
0436 fe->ops.i2c_gate_ctrl(fe, 1);
0437
0438 priv = kzalloc(sizeof(struct fc0012_priv), GFP_KERNEL);
0439 if (!priv) {
0440 ret = -ENOMEM;
0441 dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
0442 goto err;
0443 }
0444
0445 priv->cfg = cfg;
0446 priv->i2c = i2c;
0447
0448
0449 ret = fc0012_readreg(priv, 0x00, &chip_id);
0450 if (ret < 0)
0451 goto err;
0452
0453 dev_dbg(&i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id);
0454
0455 switch (chip_id) {
0456 case 0xa1:
0457 break;
0458 default:
0459 ret = -ENODEV;
0460 goto err;
0461 }
0462
0463 dev_info(&i2c->dev, "%s: Fitipower FC0012 successfully identified\n",
0464 KBUILD_MODNAME);
0465
0466 if (priv->cfg->loop_through) {
0467 ret = fc0012_writereg(priv, 0x09, 0x6f);
0468 if (ret < 0)
0469 goto err;
0470 }
0471
0472
0473
0474
0475
0476 if (priv->cfg->clock_out) {
0477 ret = fc0012_writereg(priv, 0x0b, 0x82);
0478 if (ret < 0)
0479 goto err;
0480 }
0481
0482 fe->tuner_priv = priv;
0483 memcpy(&fe->ops.tuner_ops, &fc0012_tuner_ops,
0484 sizeof(struct dvb_tuner_ops));
0485
0486 err:
0487 if (fe->ops.i2c_gate_ctrl)
0488 fe->ops.i2c_gate_ctrl(fe, 0);
0489
0490 if (ret) {
0491 dev_dbg(&i2c->dev, "%s: failed: %d\n", __func__, ret);
0492 kfree(priv);
0493 return NULL;
0494 }
0495
0496 return fe;
0497 }
0498 EXPORT_SYMBOL(fc0012_attach);
0499
0500 MODULE_DESCRIPTION("Fitipower FC0012 silicon tuner driver");
0501 MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
0502 MODULE_LICENSE("GPL");
0503 MODULE_VERSION("0.6");