0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/delay.h>
0010 #include <linux/dvb/frontend.h>
0011 #include <linux/i2c.h>
0012 #include <linux/slab.h>
0013
0014 #include <media/dvb_frontend.h>
0015 #include "mt2266.h"
0016
0017 #define I2C_ADDRESS 0x60
0018
0019 #define REG_PART_REV 0
0020 #define REG_TUNE 1
0021 #define REG_BAND 6
0022 #define REG_BANDWIDTH 8
0023 #define REG_LOCK 0x12
0024
0025 #define PART_REV 0x85
0026
0027 struct mt2266_priv {
0028 struct mt2266_config *cfg;
0029 struct i2c_adapter *i2c;
0030
0031 u32 frequency;
0032 u32 bandwidth;
0033 u8 band;
0034 };
0035
0036 #define MT2266_VHF 1
0037 #define MT2266_UHF 0
0038
0039
0040
0041 static int debug;
0042 module_param(debug, int, 0644);
0043 MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
0044
0045 #define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2266: " args); printk("\n"); }} while (0)
0046
0047
0048 static int mt2266_readreg(struct mt2266_priv *priv, u8 reg, u8 *val)
0049 {
0050 struct i2c_msg msg[2] = {
0051 { .addr = priv->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 },
0052 { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val, .len = 1 },
0053 };
0054 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
0055 printk(KERN_WARNING "MT2266 I2C read failed\n");
0056 return -EREMOTEIO;
0057 }
0058 return 0;
0059 }
0060
0061
0062 static int mt2266_writereg(struct mt2266_priv *priv, u8 reg, u8 val)
0063 {
0064 u8 buf[2] = { reg, val };
0065 struct i2c_msg msg = {
0066 .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
0067 };
0068 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
0069 printk(KERN_WARNING "MT2266 I2C write failed\n");
0070 return -EREMOTEIO;
0071 }
0072 return 0;
0073 }
0074
0075
0076 static int mt2266_writeregs(struct mt2266_priv *priv,u8 *buf, u8 len)
0077 {
0078 struct i2c_msg msg = {
0079 .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
0080 };
0081 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
0082 printk(KERN_WARNING "MT2266 I2C write failed (len=%i)\n",(int)len);
0083 return -EREMOTEIO;
0084 }
0085 return 0;
0086 }
0087
0088
0089 static u8 mt2266_init1[] = { REG_TUNE, 0x00, 0x00, 0x28,
0090 0x00, 0x52, 0x99, 0x3f };
0091
0092 static u8 mt2266_init2[] = {
0093 0x17, 0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a, 0xd4,
0094 0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14,
0095 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff,
0096 0xff, 0x00, 0x77, 0x0f, 0x2d
0097 };
0098
0099 static u8 mt2266_init_8mhz[] = { REG_BANDWIDTH, 0x22, 0x22, 0x22, 0x22,
0100 0x22, 0x22, 0x22, 0x22 };
0101
0102 static u8 mt2266_init_7mhz[] = { REG_BANDWIDTH, 0x32, 0x32, 0x32, 0x32,
0103 0x32, 0x32, 0x32, 0x32 };
0104
0105 static u8 mt2266_init_6mhz[] = { REG_BANDWIDTH, 0xa7, 0xa7, 0xa7, 0xa7,
0106 0xa7, 0xa7, 0xa7, 0xa7 };
0107
0108 static u8 mt2266_uhf[] = { 0x1d, 0xdc, 0x00, 0x0a, 0xd4, 0x03, 0x64, 0x64,
0109 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14 };
0110
0111 static u8 mt2266_vhf[] = { 0x1d, 0xfe, 0x00, 0x00, 0xb4, 0x03, 0xa5, 0xa5,
0112 0xa5, 0xa5, 0x82, 0xaa, 0xf1, 0x17, 0x80, 0x1f };
0113
0114 #define FREF 30000
0115
0116 static int mt2266_set_params(struct dvb_frontend *fe)
0117 {
0118 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0119 struct mt2266_priv *priv;
0120 int ret=0;
0121 u32 freq;
0122 u32 tune;
0123 u8 lnaband;
0124 u8 b[10];
0125 int i;
0126 u8 band;
0127
0128 priv = fe->tuner_priv;
0129
0130 freq = priv->frequency / 1000;
0131 if (freq < 470000 && freq > 230000)
0132 return -EINVAL;
0133
0134 priv->frequency = c->frequency;
0135 tune = 2 * freq * (8192/16) / (FREF/16);
0136 band = (freq < 300000) ? MT2266_VHF : MT2266_UHF;
0137 if (band == MT2266_VHF)
0138 tune *= 2;
0139
0140 switch (c->bandwidth_hz) {
0141 case 6000000:
0142 mt2266_writeregs(priv, mt2266_init_6mhz,
0143 sizeof(mt2266_init_6mhz));
0144 break;
0145 case 8000000:
0146 mt2266_writeregs(priv, mt2266_init_8mhz,
0147 sizeof(mt2266_init_8mhz));
0148 break;
0149 case 7000000:
0150 default:
0151 mt2266_writeregs(priv, mt2266_init_7mhz,
0152 sizeof(mt2266_init_7mhz));
0153 break;
0154 }
0155 priv->bandwidth = c->bandwidth_hz;
0156
0157 if (band == MT2266_VHF && priv->band == MT2266_UHF) {
0158 dprintk("Switch from UHF to VHF");
0159 mt2266_writereg(priv, 0x05, 0x04);
0160 mt2266_writereg(priv, 0x19, 0x61);
0161 mt2266_writeregs(priv, mt2266_vhf, sizeof(mt2266_vhf));
0162 } else if (band == MT2266_UHF && priv->band == MT2266_VHF) {
0163 dprintk("Switch from VHF to UHF");
0164 mt2266_writereg(priv, 0x05, 0x52);
0165 mt2266_writereg(priv, 0x19, 0x61);
0166 mt2266_writeregs(priv, mt2266_uhf, sizeof(mt2266_uhf));
0167 }
0168 msleep(10);
0169
0170 if (freq <= 495000)
0171 lnaband = 0xEE;
0172 else if (freq <= 525000)
0173 lnaband = 0xDD;
0174 else if (freq <= 550000)
0175 lnaband = 0xCC;
0176 else if (freq <= 580000)
0177 lnaband = 0xBB;
0178 else if (freq <= 605000)
0179 lnaband = 0xAA;
0180 else if (freq <= 630000)
0181 lnaband = 0x99;
0182 else if (freq <= 655000)
0183 lnaband = 0x88;
0184 else if (freq <= 685000)
0185 lnaband = 0x77;
0186 else if (freq <= 710000)
0187 lnaband = 0x66;
0188 else if (freq <= 735000)
0189 lnaband = 0x55;
0190 else if (freq <= 765000)
0191 lnaband = 0x44;
0192 else if (freq <= 802000)
0193 lnaband = 0x33;
0194 else if (freq <= 840000)
0195 lnaband = 0x22;
0196 else
0197 lnaband = 0x11;
0198
0199 b[0] = REG_TUNE;
0200 b[1] = (tune >> 8) & 0x1F;
0201 b[2] = tune & 0xFF;
0202 b[3] = tune >> 13;
0203 mt2266_writeregs(priv,b,4);
0204
0205 dprintk("set_parms: tune=%d band=%d %s",
0206 (int) tune, (int) lnaband,
0207 (band == MT2266_UHF) ? "UHF" : "VHF");
0208 dprintk("set_parms: [1..3]: %2x %2x %2x",
0209 (int) b[1], (int) b[2], (int)b[3]);
0210
0211 if (band == MT2266_UHF) {
0212 b[0] = 0x05;
0213 b[1] = (priv->band == MT2266_VHF) ? 0x52 : 0x62;
0214 b[2] = lnaband;
0215 mt2266_writeregs(priv, b, 3);
0216 }
0217
0218
0219 i = 0;
0220 do {
0221 mt2266_readreg(priv,REG_LOCK,b);
0222 if (b[0] & 0x40)
0223 break;
0224 msleep(10);
0225 i++;
0226 } while (i<10);
0227 dprintk("Lock when i=%i",(int)i);
0228
0229 if (band == MT2266_UHF && priv->band == MT2266_VHF)
0230 mt2266_writereg(priv, 0x05, 0x62);
0231
0232 priv->band = band;
0233
0234 return ret;
0235 }
0236
0237 static void mt2266_calibrate(struct mt2266_priv *priv)
0238 {
0239 mt2266_writereg(priv, 0x11, 0x03);
0240 mt2266_writereg(priv, 0x11, 0x01);
0241 mt2266_writeregs(priv, mt2266_init1, sizeof(mt2266_init1));
0242 mt2266_writeregs(priv, mt2266_init2, sizeof(mt2266_init2));
0243 mt2266_writereg(priv, 0x33, 0x5e);
0244 mt2266_writereg(priv, 0x10, 0x10);
0245 mt2266_writereg(priv, 0x10, 0x00);
0246 mt2266_writeregs(priv, mt2266_init_8mhz, sizeof(mt2266_init_8mhz));
0247 msleep(25);
0248 mt2266_writereg(priv, 0x17, 0x6d);
0249 mt2266_writereg(priv, 0x1c, 0x00);
0250 msleep(75);
0251 mt2266_writereg(priv, 0x17, 0x6d);
0252 mt2266_writereg(priv, 0x1c, 0xff);
0253 }
0254
0255 static int mt2266_get_frequency(struct dvb_frontend *fe, u32 *frequency)
0256 {
0257 struct mt2266_priv *priv = fe->tuner_priv;
0258 *frequency = priv->frequency;
0259 return 0;
0260 }
0261
0262 static int mt2266_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
0263 {
0264 struct mt2266_priv *priv = fe->tuner_priv;
0265 *bandwidth = priv->bandwidth;
0266 return 0;
0267 }
0268
0269 static int mt2266_init(struct dvb_frontend *fe)
0270 {
0271 int ret;
0272 struct mt2266_priv *priv = fe->tuner_priv;
0273 ret = mt2266_writereg(priv, 0x17, 0x6d);
0274 if (ret < 0)
0275 return ret;
0276 ret = mt2266_writereg(priv, 0x1c, 0xff);
0277 if (ret < 0)
0278 return ret;
0279 return 0;
0280 }
0281
0282 static int mt2266_sleep(struct dvb_frontend *fe)
0283 {
0284 struct mt2266_priv *priv = fe->tuner_priv;
0285 mt2266_writereg(priv, 0x17, 0x6d);
0286 mt2266_writereg(priv, 0x1c, 0x00);
0287 return 0;
0288 }
0289
0290 static void mt2266_release(struct dvb_frontend *fe)
0291 {
0292 kfree(fe->tuner_priv);
0293 fe->tuner_priv = NULL;
0294 }
0295
0296 static const struct dvb_tuner_ops mt2266_tuner_ops = {
0297 .info = {
0298 .name = "Microtune MT2266",
0299 .frequency_min_hz = 174 * MHz,
0300 .frequency_max_hz = 862 * MHz,
0301 .frequency_step_hz = 50 * kHz,
0302 },
0303 .release = mt2266_release,
0304 .init = mt2266_init,
0305 .sleep = mt2266_sleep,
0306 .set_params = mt2266_set_params,
0307 .get_frequency = mt2266_get_frequency,
0308 .get_bandwidth = mt2266_get_bandwidth
0309 };
0310
0311 struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
0312 {
0313 struct mt2266_priv *priv = NULL;
0314 u8 id = 0;
0315
0316 priv = kzalloc(sizeof(struct mt2266_priv), GFP_KERNEL);
0317 if (priv == NULL)
0318 return NULL;
0319
0320 priv->cfg = cfg;
0321 priv->i2c = i2c;
0322 priv->band = MT2266_UHF;
0323
0324 if (mt2266_readreg(priv, 0, &id)) {
0325 kfree(priv);
0326 return NULL;
0327 }
0328 if (id != PART_REV) {
0329 kfree(priv);
0330 return NULL;
0331 }
0332 printk(KERN_INFO "MT2266: successfully identified\n");
0333 memcpy(&fe->ops.tuner_ops, &mt2266_tuner_ops, sizeof(struct dvb_tuner_ops));
0334
0335 fe->tuner_priv = priv;
0336 mt2266_calibrate(priv);
0337 return fe;
0338 }
0339 EXPORT_SYMBOL(mt2266_attach);
0340
0341 MODULE_AUTHOR("Olivier DANET");
0342 MODULE_DESCRIPTION("Microtune MT2266 silicon tuner driver");
0343 MODULE_LICENSE("GPL");