0001
0002
0003
0004
0005
0006
0007
0008 #include "qt1010.h"
0009 #include "qt1010_priv.h"
0010
0011
0012 static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val)
0013 {
0014 struct i2c_msg msg[2] = {
0015 { .addr = priv->cfg->i2c_address,
0016 .flags = 0, .buf = ®, .len = 1 },
0017 { .addr = priv->cfg->i2c_address,
0018 .flags = I2C_M_RD, .buf = val, .len = 1 },
0019 };
0020
0021 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
0022 dev_warn(&priv->i2c->dev, "%s: i2c rd failed reg=%02x\n",
0023 KBUILD_MODNAME, reg);
0024 return -EREMOTEIO;
0025 }
0026 return 0;
0027 }
0028
0029
0030 static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val)
0031 {
0032 u8 buf[2] = { reg, val };
0033 struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
0034 .flags = 0, .buf = buf, .len = 2 };
0035
0036 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
0037 dev_warn(&priv->i2c->dev, "%s: i2c wr failed reg=%02x\n",
0038 KBUILD_MODNAME, reg);
0039 return -EREMOTEIO;
0040 }
0041 return 0;
0042 }
0043
0044 static int qt1010_set_params(struct dvb_frontend *fe)
0045 {
0046 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0047 struct qt1010_priv *priv;
0048 int err;
0049 u32 freq, div, mod1, mod2;
0050 u8 i, tmpval, reg05;
0051 qt1010_i2c_oper_t rd[48] = {
0052 { QT1010_WR, 0x01, 0x80 },
0053 { QT1010_WR, 0x02, 0x3f },
0054 { QT1010_WR, 0x05, 0xff },
0055 { QT1010_WR, 0x06, 0x44 },
0056 { QT1010_WR, 0x07, 0xff },
0057 { QT1010_WR, 0x08, 0x08 },
0058 { QT1010_WR, 0x09, 0xff },
0059 { QT1010_WR, 0x0a, 0xff },
0060 { QT1010_WR, 0x0b, 0xff },
0061 { QT1010_WR, 0x0c, 0xe1 },
0062 { QT1010_WR, 0x1a, 0xff },
0063 { QT1010_WR, 0x1b, 0x00 },
0064 { QT1010_WR, 0x1c, 0x89 },
0065 { QT1010_WR, 0x11, 0xff },
0066 { QT1010_WR, 0x12, 0xff },
0067 { QT1010_WR, 0x22, 0xff },
0068 { QT1010_WR, 0x1e, 0x00 },
0069 { QT1010_WR, 0x1e, 0xd0 },
0070 { QT1010_RD, 0x22, 0xff },
0071 { QT1010_WR, 0x1e, 0x00 },
0072 { QT1010_RD, 0x05, 0xff },
0073 { QT1010_RD, 0x22, 0xff },
0074 { QT1010_WR, 0x23, 0xd0 },
0075 { QT1010_WR, 0x1e, 0x00 },
0076 { QT1010_WR, 0x1e, 0xe0 },
0077 { QT1010_RD, 0x23, 0xff },
0078 { QT1010_RD, 0x23, 0xff },
0079 { QT1010_WR, 0x1e, 0x00 },
0080 { QT1010_WR, 0x24, 0xd0 },
0081 { QT1010_WR, 0x1e, 0x00 },
0082 { QT1010_WR, 0x1e, 0xf0 },
0083 { QT1010_RD, 0x24, 0xff },
0084 { QT1010_WR, 0x1e, 0x00 },
0085 { QT1010_WR, 0x14, 0x7f },
0086 { QT1010_WR, 0x15, 0x7f },
0087 { QT1010_WR, 0x05, 0xff },
0088 { QT1010_WR, 0x06, 0x00 },
0089 { QT1010_WR, 0x15, 0x1f },
0090 { QT1010_WR, 0x16, 0xff },
0091 { QT1010_WR, 0x18, 0xff },
0092 { QT1010_WR, 0x1f, 0xff },
0093 { QT1010_WR, 0x20, 0xff },
0094 { QT1010_WR, 0x21, 0x53 },
0095 { QT1010_WR, 0x25, 0xff },
0096 { QT1010_WR, 0x26, 0x15 },
0097 { QT1010_WR, 0x00, 0xff },
0098 { QT1010_WR, 0x02, 0x00 },
0099 { QT1010_WR, 0x01, 0x00 }
0100 };
0101
0102 #define FREQ1 32000000
0103 #define FREQ2 4000000
0104
0105 priv = fe->tuner_priv;
0106 freq = c->frequency;
0107 div = (freq + QT1010_OFFSET) / QT1010_STEP;
0108 freq = (div * QT1010_STEP) - QT1010_OFFSET;
0109 mod1 = (freq + QT1010_OFFSET) % FREQ1;
0110 mod2 = (freq + QT1010_OFFSET) % FREQ2;
0111 priv->frequency = freq;
0112
0113 if (fe->ops.i2c_gate_ctrl)
0114 fe->ops.i2c_gate_ctrl(fe, 1);
0115
0116
0117 if (freq < 290000000) reg05 = 0x14;
0118 else if (freq < 610000000) reg05 = 0x34;
0119 else if (freq < 802000000) reg05 = 0x54;
0120 else reg05 = 0x74;
0121
0122
0123 rd[2].val = reg05;
0124
0125
0126 rd[4].val = (freq + QT1010_OFFSET) / FREQ1;
0127
0128
0129 if (mod1 < 8000000) rd[6].val = 0x1d;
0130 else rd[6].val = 0x1c;
0131
0132
0133 if (mod1 < 1*FREQ2) rd[7].val = 0x09;
0134 else if (mod1 < 2*FREQ2) rd[7].val = 0x08;
0135 else if (mod1 < 3*FREQ2) rd[7].val = 0x0f;
0136 else if (mod1 < 4*FREQ2) rd[7].val = 0x0e;
0137 else if (mod1 < 5*FREQ2) rd[7].val = 0x0d;
0138 else if (mod1 < 6*FREQ2) rd[7].val = 0x0c;
0139 else if (mod1 < 7*FREQ2) rd[7].val = 0x0b;
0140 else rd[7].val = 0x0a;
0141
0142
0143 if (mod2 < 2000000) rd[8].val = 0x45;
0144 else rd[8].val = 0x44;
0145
0146
0147 tmpval = 0x78;
0148 rd[10].val = tmpval-((mod2/QT1010_STEP)*0x08);
0149
0150
0151 rd[13].val = 0xfd;
0152
0153
0154 rd[14].val = 0x91;
0155
0156
0157 if (freq < 450000000) rd[15].val = 0xd0;
0158 else if (freq < 482000000) rd[15].val = 0xd1;
0159 else if (freq < 514000000) rd[15].val = 0xd4;
0160 else if (freq < 546000000) rd[15].val = 0xd7;
0161 else if (freq < 610000000) rd[15].val = 0xda;
0162 else rd[15].val = 0xd0;
0163
0164
0165 rd[35].val = (reg05 & 0xf0);
0166
0167
0168 if (mod1 < 8000000) tmpval = 0x00;
0169 else if (mod1 < 12000000) tmpval = 0x01;
0170 else if (mod1 < 16000000) tmpval = 0x02;
0171 else if (mod1 < 24000000) tmpval = 0x03;
0172 else if (mod1 < 28000000) tmpval = 0x04;
0173 else tmpval = 0x05;
0174 rd[40].val = (priv->reg1f_init_val + 0x0e + tmpval);
0175
0176
0177 if (mod1 < 8000000) tmpval = 0x00;
0178 else if (mod1 < 12000000) tmpval = 0x01;
0179 else if (mod1 < 20000000) tmpval = 0x02;
0180 else if (mod1 < 24000000) tmpval = 0x03;
0181 else if (mod1 < 28000000) tmpval = 0x04;
0182 else tmpval = 0x05;
0183 rd[41].val = (priv->reg20_init_val + 0x0d + tmpval);
0184
0185
0186 rd[43].val = priv->reg25_init_val;
0187
0188
0189 rd[45].val = 0x92;
0190
0191 dev_dbg(&priv->i2c->dev,
0192 "%s: freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x " \
0193 "1a:%02x 11:%02x 12:%02x 22:%02x 05:%02x 1f:%02x " \
0194 "20:%02x 25:%02x 00:%02x\n", __func__, \
0195 freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, \
0196 rd[8].val, rd[10].val, rd[13].val, rd[14].val, \
0197 rd[15].val, rd[35].val, rd[40].val, rd[41].val, \
0198 rd[43].val, rd[45].val);
0199
0200 for (i = 0; i < ARRAY_SIZE(rd); i++) {
0201 if (rd[i].oper == QT1010_WR) {
0202 err = qt1010_writereg(priv, rd[i].reg, rd[i].val);
0203 } else {
0204 err = qt1010_readreg(priv, rd[i].reg, &tmpval);
0205 }
0206 if (err) return err;
0207 }
0208
0209 if (fe->ops.i2c_gate_ctrl)
0210 fe->ops.i2c_gate_ctrl(fe, 0);
0211
0212 return 0;
0213 }
0214
0215 static int qt1010_init_meas1(struct qt1010_priv *priv,
0216 u8 oper, u8 reg, u8 reg_init_val, u8 *retval)
0217 {
0218 u8 i, val1, val2;
0219 int err;
0220
0221 qt1010_i2c_oper_t i2c_data[] = {
0222 { QT1010_WR, reg, reg_init_val },
0223 { QT1010_WR, 0x1e, 0x00 },
0224 { QT1010_WR, 0x1e, oper },
0225 };
0226
0227 for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
0228 err = qt1010_writereg(priv, i2c_data[i].reg,
0229 i2c_data[i].val);
0230 if (err)
0231 return err;
0232 }
0233
0234 err = qt1010_readreg(priv, reg, &val2);
0235 if (err)
0236 return err;
0237 do {
0238 val1 = val2;
0239 err = qt1010_readreg(priv, reg, &val2);
0240 if (err)
0241 return err;
0242
0243 dev_dbg(&priv->i2c->dev, "%s: compare reg:%02x %02x %02x\n",
0244 __func__, reg, val1, val2);
0245 } while (val1 != val2);
0246 *retval = val1;
0247
0248 return qt1010_writereg(priv, 0x1e, 0x00);
0249 }
0250
0251 static int qt1010_init_meas2(struct qt1010_priv *priv,
0252 u8 reg_init_val, u8 *retval)
0253 {
0254 u8 i, val = 0xff;
0255 int err;
0256 qt1010_i2c_oper_t i2c_data[] = {
0257 { QT1010_WR, 0x07, reg_init_val },
0258 { QT1010_WR, 0x22, 0xd0 },
0259 { QT1010_WR, 0x1e, 0x00 },
0260 { QT1010_WR, 0x1e, 0xd0 },
0261 { QT1010_RD, 0x22, 0xff },
0262 { QT1010_WR, 0x1e, 0x00 },
0263 { QT1010_WR, 0x22, 0xff }
0264 };
0265
0266 for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
0267 if (i2c_data[i].oper == QT1010_WR) {
0268 err = qt1010_writereg(priv, i2c_data[i].reg,
0269 i2c_data[i].val);
0270 } else {
0271 err = qt1010_readreg(priv, i2c_data[i].reg, &val);
0272 }
0273 if (err)
0274 return err;
0275 }
0276 *retval = val;
0277 return 0;
0278 }
0279
0280 static int qt1010_init(struct dvb_frontend *fe)
0281 {
0282 struct qt1010_priv *priv = fe->tuner_priv;
0283 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0284 int err = 0;
0285 u8 i, tmpval, *valptr = NULL;
0286
0287 static const qt1010_i2c_oper_t i2c_data[] = {
0288 { QT1010_WR, 0x01, 0x80 },
0289 { QT1010_WR, 0x0d, 0x84 },
0290 { QT1010_WR, 0x0e, 0xb7 },
0291 { QT1010_WR, 0x2a, 0x23 },
0292 { QT1010_WR, 0x2c, 0xdc },
0293 { QT1010_M1, 0x25, 0x40 },
0294 { QT1010_M1, 0x81, 0xff },
0295 { QT1010_WR, 0x2b, 0x70 },
0296 { QT1010_WR, 0x2a, 0x23 },
0297 { QT1010_M1, 0x26, 0x08 },
0298 { QT1010_M1, 0x82, 0xff },
0299 { QT1010_WR, 0x05, 0x14 },
0300 { QT1010_WR, 0x06, 0x44 },
0301 { QT1010_WR, 0x07, 0x28 },
0302 { QT1010_WR, 0x08, 0x0b },
0303 { QT1010_WR, 0x11, 0xfd },
0304 { QT1010_M1, 0x22, 0x0d },
0305 { QT1010_M1, 0xd0, 0xff },
0306 { QT1010_WR, 0x06, 0x40 },
0307 { QT1010_WR, 0x16, 0xf0 },
0308 { QT1010_WR, 0x02, 0x38 },
0309 { QT1010_WR, 0x03, 0x18 },
0310 { QT1010_WR, 0x20, 0xe0 },
0311 { QT1010_M1, 0x1f, 0x20 },
0312 { QT1010_M1, 0x84, 0xff },
0313 { QT1010_RD, 0x20, 0x20 },
0314 { QT1010_WR, 0x03, 0x19 },
0315 { QT1010_WR, 0x02, 0x3f },
0316 { QT1010_WR, 0x21, 0x53 },
0317 { QT1010_RD, 0x21, 0xff },
0318 { QT1010_WR, 0x11, 0xfd },
0319 { QT1010_WR, 0x05, 0x34 },
0320 { QT1010_WR, 0x06, 0x44 },
0321 { QT1010_WR, 0x08, 0x08 }
0322 };
0323
0324 if (fe->ops.i2c_gate_ctrl)
0325 fe->ops.i2c_gate_ctrl(fe, 1);
0326
0327 for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
0328 switch (i2c_data[i].oper) {
0329 case QT1010_WR:
0330 err = qt1010_writereg(priv, i2c_data[i].reg,
0331 i2c_data[i].val);
0332 break;
0333 case QT1010_RD:
0334 if (i2c_data[i].val == 0x20)
0335 valptr = &priv->reg20_init_val;
0336 else
0337 valptr = &tmpval;
0338 err = qt1010_readreg(priv, i2c_data[i].reg, valptr);
0339 break;
0340 case QT1010_M1:
0341 if (i2c_data[i].val == 0x25)
0342 valptr = &priv->reg25_init_val;
0343 else if (i2c_data[i].val == 0x1f)
0344 valptr = &priv->reg1f_init_val;
0345 else
0346 valptr = &tmpval;
0347
0348 BUG_ON(i >= ARRAY_SIZE(i2c_data) - 1);
0349
0350 err = qt1010_init_meas1(priv, i2c_data[i+1].reg,
0351 i2c_data[i].reg,
0352 i2c_data[i].val, valptr);
0353 i++;
0354 break;
0355 }
0356 if (err)
0357 return err;
0358 }
0359
0360 for (i = 0x31; i < 0x3a; i++)
0361 if ((err = qt1010_init_meas2(priv, i, &tmpval)))
0362 return err;
0363
0364 if (!c->frequency)
0365 c->frequency = 545000000;
0366
0367 return qt1010_set_params(fe);
0368 }
0369
0370 static void qt1010_release(struct dvb_frontend *fe)
0371 {
0372 kfree(fe->tuner_priv);
0373 fe->tuner_priv = NULL;
0374 }
0375
0376 static int qt1010_get_frequency(struct dvb_frontend *fe, u32 *frequency)
0377 {
0378 struct qt1010_priv *priv = fe->tuner_priv;
0379 *frequency = priv->frequency;
0380 return 0;
0381 }
0382
0383 static int qt1010_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
0384 {
0385 *frequency = 36125000;
0386 return 0;
0387 }
0388
0389 static const struct dvb_tuner_ops qt1010_tuner_ops = {
0390 .info = {
0391 .name = "Quantek QT1010",
0392 .frequency_min_hz = QT1010_MIN_FREQ,
0393 .frequency_max_hz = QT1010_MAX_FREQ,
0394 .frequency_step_hz = QT1010_STEP,
0395 },
0396
0397 .release = qt1010_release,
0398 .init = qt1010_init,
0399
0400
0401 .set_params = qt1010_set_params,
0402 .get_frequency = qt1010_get_frequency,
0403 .get_if_frequency = qt1010_get_if_frequency,
0404 };
0405
0406 struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe,
0407 struct i2c_adapter *i2c,
0408 struct qt1010_config *cfg)
0409 {
0410 struct qt1010_priv *priv = NULL;
0411 u8 id;
0412
0413 priv = kzalloc(sizeof(struct qt1010_priv), GFP_KERNEL);
0414 if (priv == NULL)
0415 return NULL;
0416
0417 priv->cfg = cfg;
0418 priv->i2c = i2c;
0419
0420 if (fe->ops.i2c_gate_ctrl)
0421 fe->ops.i2c_gate_ctrl(fe, 1);
0422
0423
0424
0425 if (qt1010_readreg(priv, 0x29, &id) != 0 || (id != 0x39)) {
0426 kfree(priv);
0427 return NULL;
0428 }
0429
0430 if (fe->ops.i2c_gate_ctrl)
0431 fe->ops.i2c_gate_ctrl(fe, 0);
0432
0433 dev_info(&priv->i2c->dev,
0434 "%s: Quantek QT1010 successfully identified\n",
0435 KBUILD_MODNAME);
0436
0437 memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops,
0438 sizeof(struct dvb_tuner_ops));
0439
0440 fe->tuner_priv = priv;
0441 return fe;
0442 }
0443 EXPORT_SYMBOL(qt1010_attach);
0444
0445 MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver");
0446 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
0447 MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
0448 MODULE_VERSION("0.1");
0449 MODULE_LICENSE("GPL");