Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002   /*
0003      Driver for ST STB6000 DVBS Silicon tuner
0004 
0005      Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
0006 
0007 
0008   */
0009 
0010 #include <linux/slab.h>
0011 #include <linux/module.h>
0012 #include <linux/dvb/frontend.h>
0013 #include <asm/types.h>
0014 
0015 #include "stb6000.h"
0016 
0017 static int debug;
0018 #define dprintk(args...) \
0019     do { \
0020         if (debug) \
0021             printk(KERN_DEBUG "stb6000: " args); \
0022     } while (0)
0023 
0024 struct stb6000_priv {
0025     /* i2c details */
0026     int i2c_address;
0027     struct i2c_adapter *i2c;
0028     u32 frequency;
0029 };
0030 
0031 static void stb6000_release(struct dvb_frontend *fe)
0032 {
0033     kfree(fe->tuner_priv);
0034     fe->tuner_priv = NULL;
0035 }
0036 
0037 static int stb6000_sleep(struct dvb_frontend *fe)
0038 {
0039     struct stb6000_priv *priv = fe->tuner_priv;
0040     int ret;
0041     u8 buf[] = { 10, 0 };
0042     struct i2c_msg msg = {
0043         .addr = priv->i2c_address,
0044         .flags = 0,
0045         .buf = buf,
0046         .len = 2
0047     };
0048 
0049     dprintk("%s:\n", __func__);
0050 
0051     if (fe->ops.i2c_gate_ctrl)
0052         fe->ops.i2c_gate_ctrl(fe, 1);
0053 
0054     ret = i2c_transfer(priv->i2c, &msg, 1);
0055     if (ret != 1)
0056         dprintk("%s: i2c error\n", __func__);
0057 
0058     if (fe->ops.i2c_gate_ctrl)
0059         fe->ops.i2c_gate_ctrl(fe, 0);
0060 
0061     return (ret == 1) ? 0 : ret;
0062 }
0063 
0064 static int stb6000_set_params(struct dvb_frontend *fe)
0065 {
0066     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0067     struct stb6000_priv *priv = fe->tuner_priv;
0068     unsigned int n, m;
0069     int ret;
0070     u32 freq_mhz;
0071     int bandwidth;
0072     u8 buf[12];
0073     struct i2c_msg msg = {
0074         .addr = priv->i2c_address,
0075         .flags = 0,
0076         .buf = buf,
0077         .len = 12
0078     };
0079 
0080     dprintk("%s:\n", __func__);
0081 
0082     freq_mhz = p->frequency / 1000;
0083     bandwidth = p->symbol_rate / 1000000;
0084 
0085     if (bandwidth > 31)
0086         bandwidth = 31;
0087 
0088     if ((freq_mhz > 949) && (freq_mhz < 2151)) {
0089         buf[0] = 0x01;
0090         buf[1] = 0xac;
0091         if (freq_mhz < 1950)
0092             buf[1] = 0xaa;
0093         if (freq_mhz < 1800)
0094             buf[1] = 0xa8;
0095         if (freq_mhz < 1650)
0096             buf[1] = 0xa6;
0097         if (freq_mhz < 1530)
0098             buf[1] = 0xa5;
0099         if (freq_mhz < 1470)
0100             buf[1] = 0xa4;
0101         if (freq_mhz < 1370)
0102             buf[1] = 0xa2;
0103         if (freq_mhz < 1300)
0104             buf[1] = 0xa1;
0105         if (freq_mhz < 1200)
0106             buf[1] = 0xa0;
0107         if (freq_mhz < 1075)
0108             buf[1] = 0xbc;
0109         if (freq_mhz < 1000)
0110             buf[1] = 0xba;
0111         if (freq_mhz < 1075) {
0112             n = freq_mhz / 8; /* vco=lo*4 */
0113             m = 2;
0114         } else {
0115             n = freq_mhz / 16; /* vco=lo*2 */
0116             m = 1;
0117         }
0118         buf[2] = n >> 1;
0119         buf[3] = (unsigned char)(((n & 1) << 7) |
0120                     (m * freq_mhz - n * 16) | 0x60);
0121         buf[4] = 0x04;
0122         buf[5] = 0x0e;
0123 
0124         buf[6] = (unsigned char)(bandwidth);
0125 
0126         buf[7] = 0xd8;
0127         buf[8] = 0xd0;
0128         buf[9] = 0x50;
0129         buf[10] = 0xeb;
0130         buf[11] = 0x4f;
0131 
0132         if (fe->ops.i2c_gate_ctrl)
0133             fe->ops.i2c_gate_ctrl(fe, 1);
0134 
0135         ret = i2c_transfer(priv->i2c, &msg, 1);
0136         if (ret != 1)
0137             dprintk("%s: i2c error\n", __func__);
0138 
0139         udelay(10);
0140         if (fe->ops.i2c_gate_ctrl)
0141             fe->ops.i2c_gate_ctrl(fe, 0);
0142 
0143         buf[0] = 0x07;
0144         buf[1] = 0xdf;
0145         buf[2] = 0xd0;
0146         buf[3] = 0x50;
0147         buf[4] = 0xfb;
0148         msg.len = 5;
0149 
0150         if (fe->ops.i2c_gate_ctrl)
0151             fe->ops.i2c_gate_ctrl(fe, 1);
0152 
0153         ret = i2c_transfer(priv->i2c, &msg, 1);
0154         if (ret != 1)
0155             dprintk("%s: i2c error\n", __func__);
0156 
0157         udelay(10);
0158         if (fe->ops.i2c_gate_ctrl)
0159             fe->ops.i2c_gate_ctrl(fe, 0);
0160 
0161         priv->frequency = freq_mhz * 1000;
0162 
0163         return (ret == 1) ? 0 : ret;
0164     }
0165     return -1;
0166 }
0167 
0168 static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
0169 {
0170     struct stb6000_priv *priv = fe->tuner_priv;
0171     *frequency = priv->frequency;
0172     return 0;
0173 }
0174 
0175 static const struct dvb_tuner_ops stb6000_tuner_ops = {
0176     .info = {
0177         .name = "ST STB6000",
0178         .frequency_min_hz =  950 * MHz,
0179         .frequency_max_hz = 2150 * MHz
0180     },
0181     .release = stb6000_release,
0182     .sleep = stb6000_sleep,
0183     .set_params = stb6000_set_params,
0184     .get_frequency = stb6000_get_frequency,
0185 };
0186 
0187 struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
0188                         struct i2c_adapter *i2c)
0189 {
0190     struct stb6000_priv *priv = NULL;
0191     u8 b0[] = { 0 };
0192     u8 b1[] = { 0, 0 };
0193     struct i2c_msg msg[2] = {
0194         {
0195             .addr = addr,
0196             .flags = 0,
0197             .buf = b0,
0198             .len = 0
0199         }, {
0200             .addr = addr,
0201             .flags = I2C_M_RD,
0202             .buf = b1,
0203             .len = 2
0204         }
0205     };
0206     int ret;
0207 
0208     dprintk("%s:\n", __func__);
0209 
0210     if (fe->ops.i2c_gate_ctrl)
0211         fe->ops.i2c_gate_ctrl(fe, 1);
0212 
0213     /* is some i2c device here ? */
0214     ret = i2c_transfer(i2c, msg, 2);
0215     if (fe->ops.i2c_gate_ctrl)
0216         fe->ops.i2c_gate_ctrl(fe, 0);
0217 
0218     if (ret != 2)
0219         return NULL;
0220 
0221     priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL);
0222     if (priv == NULL)
0223         return NULL;
0224 
0225     priv->i2c_address = addr;
0226     priv->i2c = i2c;
0227 
0228     memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops,
0229                 sizeof(struct dvb_tuner_ops));
0230 
0231     fe->tuner_priv = priv;
0232 
0233     return fe;
0234 }
0235 EXPORT_SYMBOL(stb6000_attach);
0236 
0237 module_param(debug, int, 0644);
0238 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
0239 
0240 MODULE_DESCRIPTION("DVB STB6000 driver");
0241 MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
0242 MODULE_LICENSE("GPL");