Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003     Driver for ST STV0288 demodulator
0004     Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
0005         for Reel Multimedia
0006     Copyright (C) 2008 TurboSight.com, Bob Liu <bob@turbosight.com>
0007     Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
0008         Removed stb6000 specific tuner code and revised some
0009         procedures.
0010     2010-09-01 Josef Pavlik <josef@pavlik.it>
0011         Fixed diseqc_msg, diseqc_burst and set_tone problems
0012 
0013 
0014 */
0015 
0016 #include <linux/init.h>
0017 #include <linux/kernel.h>
0018 #include <linux/module.h>
0019 #include <linux/string.h>
0020 #include <linux/slab.h>
0021 #include <linux/jiffies.h>
0022 #include <asm/div64.h>
0023 
0024 #include <media/dvb_frontend.h>
0025 #include "stv0288.h"
0026 
0027 struct stv0288_state {
0028     struct i2c_adapter *i2c;
0029     const struct stv0288_config *config;
0030     struct dvb_frontend frontend;
0031 
0032     u8 initialised:1;
0033     u32 tuner_frequency;
0034     u32 symbol_rate;
0035     enum fe_code_rate fec_inner;
0036     int errmode;
0037 };
0038 
0039 #define STATUS_BER 0
0040 #define STATUS_UCBLOCKS 1
0041 
0042 static int debug;
0043 static int debug_legacy_dish_switch;
0044 #define dprintk(args...) \
0045     do { \
0046         if (debug) \
0047             printk(KERN_DEBUG "stv0288: " args); \
0048     } while (0)
0049 
0050 
0051 static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data)
0052 {
0053     int ret;
0054     u8 buf[] = { reg, data };
0055     struct i2c_msg msg = {
0056         .addr = state->config->demod_address,
0057         .flags = 0,
0058         .buf = buf,
0059         .len = 2
0060     };
0061 
0062     ret = i2c_transfer(state->i2c, &msg, 1);
0063 
0064     if (ret != 1)
0065         dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
0066             __func__, reg, data, ret);
0067 
0068     return (ret != 1) ? -EREMOTEIO : 0;
0069 }
0070 
0071 static int stv0288_write(struct dvb_frontend *fe, const u8 buf[], int len)
0072 {
0073     struct stv0288_state *state = fe->demodulator_priv;
0074 
0075     if (len != 2)
0076         return -EINVAL;
0077 
0078     return stv0288_writeregI(state, buf[0], buf[1]);
0079 }
0080 
0081 static u8 stv0288_readreg(struct stv0288_state *state, u8 reg)
0082 {
0083     int ret;
0084     u8 b0[] = { reg };
0085     u8 b1[] = { 0 };
0086     struct i2c_msg msg[] = {
0087         {
0088             .addr = state->config->demod_address,
0089             .flags = 0,
0090             .buf = b0,
0091             .len = 1
0092         }, {
0093             .addr = state->config->demod_address,
0094             .flags = I2C_M_RD,
0095             .buf = b1,
0096             .len = 1
0097         }
0098     };
0099 
0100     ret = i2c_transfer(state->i2c, msg, 2);
0101 
0102     if (ret != 2)
0103         dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
0104                 __func__, reg, ret);
0105 
0106     return b1[0];
0107 }
0108 
0109 static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate)
0110 {
0111     struct stv0288_state *state = fe->demodulator_priv;
0112     unsigned int temp;
0113     unsigned char b[3];
0114 
0115     if ((srate < 1000000) || (srate > 45000000))
0116         return -EINVAL;
0117 
0118     stv0288_writeregI(state, 0x22, 0);
0119     stv0288_writeregI(state, 0x23, 0);
0120     stv0288_writeregI(state, 0x2b, 0xff);
0121     stv0288_writeregI(state, 0x2c, 0xf7);
0122 
0123     temp = (unsigned int)srate / 1000;
0124 
0125     temp = temp * 32768;
0126     temp = temp / 25;
0127     temp = temp / 125;
0128     b[0] = (unsigned char)((temp >> 12) & 0xff);
0129     b[1] = (unsigned char)((temp >> 4) & 0xff);
0130     b[2] = (unsigned char)((temp << 4) & 0xf0);
0131     stv0288_writeregI(state, 0x28, 0x80); /* SFRH */
0132     stv0288_writeregI(state, 0x29, 0); /* SFRM */
0133     stv0288_writeregI(state, 0x2a, 0); /* SFRL */
0134 
0135     stv0288_writeregI(state, 0x28, b[0]);
0136     stv0288_writeregI(state, 0x29, b[1]);
0137     stv0288_writeregI(state, 0x2a, b[2]);
0138     dprintk("stv0288: stv0288_set_symbolrate\n");
0139 
0140     return 0;
0141 }
0142 
0143 static int stv0288_send_diseqc_msg(struct dvb_frontend *fe,
0144                     struct dvb_diseqc_master_cmd *m)
0145 {
0146     struct stv0288_state *state = fe->demodulator_priv;
0147 
0148     int i;
0149 
0150     dprintk("%s\n", __func__);
0151 
0152     stv0288_writeregI(state, 0x09, 0);
0153     msleep(30);
0154     stv0288_writeregI(state, 0x05, 0x12);/* modulated mode, single shot */
0155 
0156     for (i = 0; i < m->msg_len; i++) {
0157         if (stv0288_writeregI(state, 0x06, m->msg[i]))
0158             return -EREMOTEIO;
0159     }
0160     msleep(m->msg_len*12);
0161     return 0;
0162 }
0163 
0164 static int stv0288_send_diseqc_burst(struct dvb_frontend *fe,
0165                      enum fe_sec_mini_cmd burst)
0166 {
0167     struct stv0288_state *state = fe->demodulator_priv;
0168 
0169     dprintk("%s\n", __func__);
0170 
0171     if (stv0288_writeregI(state, 0x05, 0x03))/* burst mode, single shot */
0172         return -EREMOTEIO;
0173 
0174     if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff))
0175         return -EREMOTEIO;
0176 
0177     msleep(15);
0178     if (stv0288_writeregI(state, 0x05, 0x12))
0179         return -EREMOTEIO;
0180 
0181     return 0;
0182 }
0183 
0184 static int stv0288_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
0185 {
0186     struct stv0288_state *state = fe->demodulator_priv;
0187 
0188     switch (tone) {
0189     case SEC_TONE_ON:
0190         if (stv0288_writeregI(state, 0x05, 0x10))/* cont carrier */
0191             return -EREMOTEIO;
0192     break;
0193 
0194     case SEC_TONE_OFF:
0195         if (stv0288_writeregI(state, 0x05, 0x12))/* burst mode off*/
0196             return -EREMOTEIO;
0197     break;
0198 
0199     default:
0200         return -EINVAL;
0201     }
0202     return 0;
0203 }
0204 
0205 static u8 stv0288_inittab[] = {
0206     0x01, 0x15,
0207     0x02, 0x20,
0208     0x09, 0x0,
0209     0x0a, 0x4,
0210     0x0b, 0x0,
0211     0x0c, 0x0,
0212     0x0d, 0x0,
0213     0x0e, 0xd4,
0214     0x0f, 0x30,
0215     0x11, 0x80,
0216     0x12, 0x03,
0217     0x13, 0x48,
0218     0x14, 0x84,
0219     0x15, 0x45,
0220     0x16, 0xb7,
0221     0x17, 0x9c,
0222     0x18, 0x0,
0223     0x19, 0xa6,
0224     0x1a, 0x88,
0225     0x1b, 0x8f,
0226     0x1c, 0xf0,
0227     0x20, 0x0b,
0228     0x21, 0x54,
0229     0x22, 0x0,
0230     0x23, 0x0,
0231     0x2b, 0xff,
0232     0x2c, 0xf7,
0233     0x30, 0x0,
0234     0x31, 0x1e,
0235     0x32, 0x14,
0236     0x33, 0x0f,
0237     0x34, 0x09,
0238     0x35, 0x0c,
0239     0x36, 0x05,
0240     0x37, 0x2f,
0241     0x38, 0x16,
0242     0x39, 0xbe,
0243     0x3a, 0x0,
0244     0x3b, 0x13,
0245     0x3c, 0x11,
0246     0x3d, 0x30,
0247     0x40, 0x63,
0248     0x41, 0x04,
0249     0x42, 0x20,
0250     0x43, 0x00,
0251     0x44, 0x00,
0252     0x45, 0x00,
0253     0x46, 0x00,
0254     0x47, 0x00,
0255     0x4a, 0x00,
0256     0x50, 0x10,
0257     0x51, 0x38,
0258     0x52, 0x21,
0259     0x58, 0x54,
0260     0x59, 0x86,
0261     0x5a, 0x0,
0262     0x5b, 0x9b,
0263     0x5c, 0x08,
0264     0x5d, 0x7f,
0265     0x5e, 0x0,
0266     0x5f, 0xff,
0267     0x70, 0x0,
0268     0x71, 0x0,
0269     0x72, 0x0,
0270     0x74, 0x0,
0271     0x75, 0x0,
0272     0x76, 0x0,
0273     0x81, 0x0,
0274     0x82, 0x3f,
0275     0x83, 0x3f,
0276     0x84, 0x0,
0277     0x85, 0x0,
0278     0x88, 0x0,
0279     0x89, 0x0,
0280     0x8a, 0x0,
0281     0x8b, 0x0,
0282     0x8c, 0x0,
0283     0x90, 0x0,
0284     0x91, 0x0,
0285     0x92, 0x0,
0286     0x93, 0x0,
0287     0x94, 0x1c,
0288     0x97, 0x0,
0289     0xa0, 0x48,
0290     0xa1, 0x0,
0291     0xb0, 0xb8,
0292     0xb1, 0x3a,
0293     0xb2, 0x10,
0294     0xb3, 0x82,
0295     0xb4, 0x80,
0296     0xb5, 0x82,
0297     0xb6, 0x82,
0298     0xb7, 0x82,
0299     0xb8, 0x20,
0300     0xb9, 0x0,
0301     0xf0, 0x0,
0302     0xf1, 0x0,
0303     0xf2, 0xc0,
0304     0x51, 0x36,
0305     0x52, 0x09,
0306     0x53, 0x94,
0307     0x54, 0x62,
0308     0x55, 0x29,
0309     0x56, 0x64,
0310     0x57, 0x2b,
0311     0xff, 0xff,
0312 };
0313 
0314 static int stv0288_set_voltage(struct dvb_frontend *fe,
0315                    enum fe_sec_voltage volt)
0316 {
0317     dprintk("%s: %s\n", __func__,
0318         volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
0319         volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
0320 
0321     return 0;
0322 }
0323 
0324 static int stv0288_init(struct dvb_frontend *fe)
0325 {
0326     struct stv0288_state *state = fe->demodulator_priv;
0327     int i;
0328     u8 reg;
0329     u8 val;
0330 
0331     dprintk("stv0288: init chip\n");
0332     stv0288_writeregI(state, 0x41, 0x04);
0333     msleep(50);
0334 
0335     /* we have default inittab */
0336     if (state->config->inittab == NULL) {
0337         for (i = 0; !(stv0288_inittab[i] == 0xff &&
0338                 stv0288_inittab[i + 1] == 0xff); i += 2)
0339             stv0288_writeregI(state, stv0288_inittab[i],
0340                     stv0288_inittab[i + 1]);
0341     } else {
0342         for (i = 0; ; i += 2)  {
0343             reg = state->config->inittab[i];
0344             val = state->config->inittab[i+1];
0345             if (reg == 0xff && val == 0xff)
0346                 break;
0347             stv0288_writeregI(state, reg, val);
0348         }
0349     }
0350     return 0;
0351 }
0352 
0353 static int stv0288_read_status(struct dvb_frontend *fe, enum fe_status *status)
0354 {
0355     struct stv0288_state *state = fe->demodulator_priv;
0356 
0357     u8 sync = stv0288_readreg(state, 0x24);
0358     if (sync == 255)
0359         sync = 0;
0360 
0361     dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
0362 
0363     *status = 0;
0364     if (sync & 0x80)
0365         *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
0366     if (sync & 0x10)
0367         *status |= FE_HAS_VITERBI;
0368     if (sync & 0x08) {
0369         *status |= FE_HAS_LOCK;
0370         dprintk("stv0288 has locked\n");
0371     }
0372 
0373     return 0;
0374 }
0375 
0376 static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber)
0377 {
0378     struct stv0288_state *state = fe->demodulator_priv;
0379 
0380     if (state->errmode != STATUS_BER)
0381         return 0;
0382     *ber = (stv0288_readreg(state, 0x26) << 8) |
0383                     stv0288_readreg(state, 0x27);
0384     dprintk("stv0288_read_ber %d\n", *ber);
0385 
0386     return 0;
0387 }
0388 
0389 
0390 static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
0391 {
0392     struct stv0288_state *state = fe->demodulator_priv;
0393 
0394     s32 signal =  0xffff - ((stv0288_readreg(state, 0x10) << 8));
0395 
0396 
0397     signal = signal * 5 / 4;
0398     *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
0399     dprintk("stv0288_read_signal_strength %d\n", *strength);
0400 
0401     return 0;
0402 }
0403 static int stv0288_sleep(struct dvb_frontend *fe)
0404 {
0405     struct stv0288_state *state = fe->demodulator_priv;
0406 
0407     stv0288_writeregI(state, 0x41, 0x84);
0408     state->initialised = 0;
0409 
0410     return 0;
0411 }
0412 static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr)
0413 {
0414     struct stv0288_state *state = fe->demodulator_priv;
0415 
0416     s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8)
0417                | stv0288_readreg(state, 0x2e));
0418     xsnr = 3 * (xsnr - 0xa100);
0419     *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
0420     dprintk("stv0288_read_snr %d\n", *snr);
0421 
0422     return 0;
0423 }
0424 
0425 static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
0426 {
0427     struct stv0288_state *state = fe->demodulator_priv;
0428 
0429     if (state->errmode != STATUS_BER)
0430         return 0;
0431     *ucblocks = (stv0288_readreg(state, 0x26) << 8) |
0432                     stv0288_readreg(state, 0x27);
0433     dprintk("stv0288_read_ber %d\n", *ucblocks);
0434 
0435     return 0;
0436 }
0437 
0438 static int stv0288_set_frontend(struct dvb_frontend *fe)
0439 {
0440     struct stv0288_state *state = fe->demodulator_priv;
0441     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0442 
0443     char tm;
0444     unsigned char tda[3];
0445     u8 reg, time_out = 0;
0446 
0447     dprintk("%s : FE_SET_FRONTEND\n", __func__);
0448 
0449     if (c->delivery_system != SYS_DVBS) {
0450         dprintk("%s: unsupported delivery system selected (%d)\n",
0451             __func__, c->delivery_system);
0452         return -EOPNOTSUPP;
0453     }
0454 
0455     if (state->config->set_ts_params)
0456         state->config->set_ts_params(fe, 0);
0457 
0458     /* only frequency & symbol_rate are used for tuner*/
0459     if (fe->ops.tuner_ops.set_params) {
0460         fe->ops.tuner_ops.set_params(fe);
0461         if (fe->ops.i2c_gate_ctrl)
0462             fe->ops.i2c_gate_ctrl(fe, 0);
0463     }
0464 
0465     udelay(10);
0466     stv0288_set_symbolrate(fe, c->symbol_rate);
0467     /* Carrier lock control register */
0468     stv0288_writeregI(state, 0x15, 0xc5);
0469 
0470     tda[2] = 0x0; /* CFRL */
0471     for (tm = -9; tm < 7;) {
0472         /* Viterbi status */
0473         reg = stv0288_readreg(state, 0x24);
0474         if (reg & 0x8)
0475                 break;
0476         if (reg & 0x80) {
0477             time_out++;
0478             if (time_out > 10)
0479                 break;
0480             tda[2] += 40;
0481             if (tda[2] < 40)
0482                 tm++;
0483         } else {
0484             tm++;
0485             tda[2] = 0;
0486             time_out = 0;
0487         }
0488         tda[1] = (unsigned char)tm;
0489         stv0288_writeregI(state, 0x2b, tda[1]);
0490         stv0288_writeregI(state, 0x2c, tda[2]);
0491         msleep(30);
0492     }
0493     state->tuner_frequency = c->frequency;
0494     state->fec_inner = FEC_AUTO;
0495     state->symbol_rate = c->symbol_rate;
0496 
0497     return 0;
0498 }
0499 
0500 static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
0501 {
0502     struct stv0288_state *state = fe->demodulator_priv;
0503 
0504     if (enable)
0505         stv0288_writeregI(state, 0x01, 0xb5);
0506     else
0507         stv0288_writeregI(state, 0x01, 0x35);
0508 
0509     udelay(1);
0510 
0511     return 0;
0512 }
0513 
0514 static void stv0288_release(struct dvb_frontend *fe)
0515 {
0516     struct stv0288_state *state = fe->demodulator_priv;
0517     kfree(state);
0518 }
0519 
0520 static const struct dvb_frontend_ops stv0288_ops = {
0521     .delsys = { SYS_DVBS },
0522     .info = {
0523         .name           = "ST STV0288 DVB-S",
0524         .frequency_min_hz   =  950 * MHz,
0525         .frequency_max_hz   = 2150 * MHz,
0526         .frequency_stepsize_hz  =    1 * MHz,
0527         .symbol_rate_min    = 1000000,
0528         .symbol_rate_max    = 45000000,
0529         .symbol_rate_tolerance  = 500,  /* ppm */
0530         .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
0531               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
0532               FE_CAN_QPSK |
0533               FE_CAN_FEC_AUTO
0534     },
0535 
0536     .release = stv0288_release,
0537     .init = stv0288_init,
0538     .sleep = stv0288_sleep,
0539     .write = stv0288_write,
0540     .i2c_gate_ctrl = stv0288_i2c_gate_ctrl,
0541     .read_status = stv0288_read_status,
0542     .read_ber = stv0288_read_ber,
0543     .read_signal_strength = stv0288_read_signal_strength,
0544     .read_snr = stv0288_read_snr,
0545     .read_ucblocks = stv0288_read_ucblocks,
0546     .diseqc_send_master_cmd = stv0288_send_diseqc_msg,
0547     .diseqc_send_burst = stv0288_send_diseqc_burst,
0548     .set_tone = stv0288_set_tone,
0549     .set_voltage = stv0288_set_voltage,
0550 
0551     .set_frontend = stv0288_set_frontend,
0552 };
0553 
0554 struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
0555                     struct i2c_adapter *i2c)
0556 {
0557     struct stv0288_state *state = NULL;
0558     int id;
0559 
0560     /* allocate memory for the internal state */
0561     state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
0562     if (state == NULL)
0563         goto error;
0564 
0565     /* setup the state */
0566     state->config = config;
0567     state->i2c = i2c;
0568     state->initialised = 0;
0569     state->tuner_frequency = 0;
0570     state->symbol_rate = 0;
0571     state->fec_inner = 0;
0572     state->errmode = STATUS_BER;
0573 
0574     stv0288_writeregI(state, 0x41, 0x04);
0575     msleep(200);
0576     id = stv0288_readreg(state, 0x00);
0577     dprintk("stv0288 id %x\n", id);
0578 
0579     /* register 0x00 contains 0x11 for STV0288  */
0580     if (id != 0x11)
0581         goto error;
0582 
0583     /* create dvb_frontend */
0584     memcpy(&state->frontend.ops, &stv0288_ops,
0585             sizeof(struct dvb_frontend_ops));
0586     state->frontend.demodulator_priv = state;
0587     return &state->frontend;
0588 
0589 error:
0590     kfree(state);
0591 
0592     return NULL;
0593 }
0594 EXPORT_SYMBOL(stv0288_attach);
0595 
0596 module_param(debug_legacy_dish_switch, int, 0444);
0597 MODULE_PARM_DESC(debug_legacy_dish_switch,
0598         "Enable timing analysis for Dish Network legacy switches");
0599 
0600 module_param(debug, int, 0644);
0601 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
0602 
0603 MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
0604 MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
0605 MODULE_LICENSE("GPL");
0606