Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
0004  *
0005  *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
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 
0016 #include "mt2131.h"
0017 #include "mt2131_priv.h"
0018 
0019 static int debug;
0020 module_param(debug, int, 0644);
0021 MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
0022 
0023 #define dprintk(level,fmt, arg...) if (debug >= level) \
0024     printk(KERN_INFO "%s: " fmt, "mt2131", ## arg)
0025 
0026 static u8 mt2131_config1[] = {
0027     0x01,
0028     0x50, 0x00, 0x50, 0x80, 0x00, 0x49, 0xfa, 0x88,
0029     0x08, 0x77, 0x41, 0x04, 0x00, 0x00, 0x00, 0x32,
0030     0x7f, 0xda, 0x4c, 0x00, 0x10, 0xaa, 0x78, 0x80,
0031     0xff, 0x68, 0xa0, 0xff, 0xdd, 0x00, 0x00
0032 };
0033 
0034 static u8 mt2131_config2[] = {
0035     0x10,
0036     0x7f, 0xc8, 0x0a, 0x5f, 0x00, 0x04
0037 };
0038 
0039 static int mt2131_readreg(struct mt2131_priv *priv, u8 reg, u8 *val)
0040 {
0041     struct i2c_msg msg[2] = {
0042         { .addr = priv->cfg->i2c_address, .flags = 0,
0043           .buf = &reg, .len = 1 },
0044         { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
0045           .buf = val,  .len = 1 },
0046     };
0047 
0048     if (i2c_transfer(priv->i2c, msg, 2) != 2) {
0049         printk(KERN_WARNING "mt2131 I2C read failed\n");
0050         return -EREMOTEIO;
0051     }
0052     return 0;
0053 }
0054 
0055 static int mt2131_writereg(struct mt2131_priv *priv, u8 reg, u8 val)
0056 {
0057     u8 buf[2] = { reg, val };
0058     struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = 0,
0059                    .buf = buf, .len = 2 };
0060 
0061     if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
0062         printk(KERN_WARNING "mt2131 I2C write failed\n");
0063         return -EREMOTEIO;
0064     }
0065     return 0;
0066 }
0067 
0068 static int mt2131_writeregs(struct mt2131_priv *priv,u8 *buf, u8 len)
0069 {
0070     struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
0071                    .flags = 0, .buf = buf, .len = len };
0072 
0073     if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
0074         printk(KERN_WARNING "mt2131 I2C write failed (len=%i)\n",
0075                (int)len);
0076         return -EREMOTEIO;
0077     }
0078     return 0;
0079 }
0080 
0081 static int mt2131_set_params(struct dvb_frontend *fe)
0082 {
0083     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0084     struct mt2131_priv *priv;
0085     int ret=0, i;
0086     u32 freq;
0087     u8  if_band_center;
0088     u32 f_lo1, f_lo2;
0089     u32 div1, num1, div2, num2;
0090     u8  b[8];
0091     u8 lockval = 0;
0092 
0093     priv = fe->tuner_priv;
0094 
0095     freq = c->frequency / 1000;  /* Hz -> kHz */
0096     dprintk(1, "%s() freq=%d\n", __func__, freq);
0097 
0098     f_lo1 = freq + MT2131_IF1 * 1000;
0099     f_lo1 = (f_lo1 / 250) * 250;
0100     f_lo2 = f_lo1 - freq - MT2131_IF2;
0101 
0102     priv->frequency =  (f_lo1 - f_lo2 - MT2131_IF2) * 1000;
0103 
0104     /* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */
0105     num1 = f_lo1 * 64 / (MT2131_FREF / 128);
0106     div1 = num1 / 8192;
0107     num1 &= 0x1fff;
0108 
0109     /* Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 ) */
0110     num2 = f_lo2 * 64 / (MT2131_FREF / 128);
0111     div2 = num2 / 8192;
0112     num2 &= 0x1fff;
0113 
0114     if (freq <=   82500) if_band_center = 0x00; else
0115     if (freq <=  137500) if_band_center = 0x01; else
0116     if (freq <=  192500) if_band_center = 0x02; else
0117     if (freq <=  247500) if_band_center = 0x03; else
0118     if (freq <=  302500) if_band_center = 0x04; else
0119     if (freq <=  357500) if_band_center = 0x05; else
0120     if (freq <=  412500) if_band_center = 0x06; else
0121     if (freq <=  467500) if_band_center = 0x07; else
0122     if (freq <=  522500) if_band_center = 0x08; else
0123     if (freq <=  577500) if_band_center = 0x09; else
0124     if (freq <=  632500) if_band_center = 0x0A; else
0125     if (freq <=  687500) if_band_center = 0x0B; else
0126     if (freq <=  742500) if_band_center = 0x0C; else
0127     if (freq <=  797500) if_band_center = 0x0D; else
0128     if (freq <=  852500) if_band_center = 0x0E; else
0129     if (freq <=  907500) if_band_center = 0x0F; else
0130     if (freq <=  962500) if_band_center = 0x10; else
0131     if (freq <= 1017500) if_band_center = 0x11; else
0132     if (freq <= 1072500) if_band_center = 0x12; else if_band_center = 0x13;
0133 
0134     b[0] = 1;
0135     b[1] = (num1 >> 5) & 0xFF;
0136     b[2] = (num1 & 0x1F);
0137     b[3] = div1;
0138     b[4] = (num2 >> 5) & 0xFF;
0139     b[5] = num2 & 0x1F;
0140     b[6] = div2;
0141 
0142     dprintk(1, "IF1: %dMHz IF2: %dMHz\n", MT2131_IF1, MT2131_IF2);
0143     dprintk(1, "PLL freq=%dkHz  band=%d\n", (int)freq, (int)if_band_center);
0144     dprintk(1, "PLL f_lo1=%dkHz  f_lo2=%dkHz\n", (int)f_lo1, (int)f_lo2);
0145     dprintk(1, "PLL div1=%d  num1=%d  div2=%d  num2=%d\n",
0146         (int)div1, (int)num1, (int)div2, (int)num2);
0147     dprintk(1, "PLL [1..6]: %2x %2x %2x %2x %2x %2x\n",
0148         (int)b[1], (int)b[2], (int)b[3], (int)b[4], (int)b[5],
0149         (int)b[6]);
0150 
0151     ret = mt2131_writeregs(priv,b,7);
0152     if (ret < 0)
0153         return ret;
0154 
0155     mt2131_writereg(priv, 0x0b, if_band_center);
0156 
0157     /* Wait for lock */
0158     i = 0;
0159     do {
0160         mt2131_readreg(priv, 0x08, &lockval);
0161         if ((lockval & 0x88) == 0x88)
0162             break;
0163         msleep(4);
0164         i++;
0165     } while (i < 10);
0166 
0167     return ret;
0168 }
0169 
0170 static int mt2131_get_frequency(struct dvb_frontend *fe, u32 *frequency)
0171 {
0172     struct mt2131_priv *priv = fe->tuner_priv;
0173     dprintk(1, "%s()\n", __func__);
0174     *frequency = priv->frequency;
0175     return 0;
0176 }
0177 
0178 static int mt2131_get_status(struct dvb_frontend *fe, u32 *status)
0179 {
0180     struct mt2131_priv *priv = fe->tuner_priv;
0181     u8 lock_status = 0;
0182     u8 afc_status = 0;
0183 
0184     *status = 0;
0185 
0186     mt2131_readreg(priv, 0x08, &lock_status);
0187     if ((lock_status & 0x88) == 0x88)
0188         *status = TUNER_STATUS_LOCKED;
0189 
0190     mt2131_readreg(priv, 0x09, &afc_status);
0191     dprintk(1, "%s() - LO Status = 0x%x, AFC Status = 0x%x\n",
0192         __func__, lock_status, afc_status);
0193 
0194     return 0;
0195 }
0196 
0197 static int mt2131_init(struct dvb_frontend *fe)
0198 {
0199     struct mt2131_priv *priv = fe->tuner_priv;
0200     int ret;
0201     dprintk(1, "%s()\n", __func__);
0202 
0203     if ((ret = mt2131_writeregs(priv, mt2131_config1,
0204                     sizeof(mt2131_config1))) < 0)
0205         return ret;
0206 
0207     mt2131_writereg(priv, 0x0b, 0x09);
0208     mt2131_writereg(priv, 0x15, 0x47);
0209     mt2131_writereg(priv, 0x07, 0xf2);
0210     mt2131_writereg(priv, 0x0b, 0x01);
0211 
0212     if ((ret = mt2131_writeregs(priv, mt2131_config2,
0213                     sizeof(mt2131_config2))) < 0)
0214         return ret;
0215 
0216     return ret;
0217 }
0218 
0219 static void mt2131_release(struct dvb_frontend *fe)
0220 {
0221     dprintk(1, "%s()\n", __func__);
0222     kfree(fe->tuner_priv);
0223     fe->tuner_priv = NULL;
0224 }
0225 
0226 static const struct dvb_tuner_ops mt2131_tuner_ops = {
0227     .info = {
0228         .name              = "Microtune MT2131",
0229         .frequency_min_hz  =  48 * MHz,
0230         .frequency_max_hz  = 860 * MHz,
0231         .frequency_step_hz =  50 * kHz,
0232     },
0233 
0234     .release       = mt2131_release,
0235     .init          = mt2131_init,
0236 
0237     .set_params    = mt2131_set_params,
0238     .get_frequency = mt2131_get_frequency,
0239     .get_status    = mt2131_get_status
0240 };
0241 
0242 struct dvb_frontend * mt2131_attach(struct dvb_frontend *fe,
0243                     struct i2c_adapter *i2c,
0244                     struct mt2131_config *cfg, u16 if1)
0245 {
0246     struct mt2131_priv *priv = NULL;
0247     u8 id = 0;
0248 
0249     dprintk(1, "%s()\n", __func__);
0250 
0251     priv = kzalloc(sizeof(struct mt2131_priv), GFP_KERNEL);
0252     if (priv == NULL)
0253         return NULL;
0254 
0255     priv->cfg = cfg;
0256     priv->i2c = i2c;
0257 
0258     if (mt2131_readreg(priv, 0, &id) != 0) {
0259         kfree(priv);
0260         return NULL;
0261     }
0262     if ( (id != 0x3E) && (id != 0x3F) ) {
0263         printk(KERN_ERR "MT2131: Device not found at addr 0x%02x\n",
0264                cfg->i2c_address);
0265         kfree(priv);
0266         return NULL;
0267     }
0268 
0269     printk(KERN_INFO "MT2131: successfully identified at address 0x%02x\n",
0270            cfg->i2c_address);
0271     memcpy(&fe->ops.tuner_ops, &mt2131_tuner_ops,
0272            sizeof(struct dvb_tuner_ops));
0273 
0274     fe->tuner_priv = priv;
0275     return fe;
0276 }
0277 EXPORT_SYMBOL(mt2131_attach);
0278 
0279 MODULE_AUTHOR("Steven Toth");
0280 MODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver");
0281 MODULE_LICENSE("GPL");