Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003     Driver for VES1893 and VES1993 QPSK Demodulators
0004 
0005     Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
0006     Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
0007     Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
0008     Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org>
0009 
0010 
0011 */
0012 
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/init.h>
0016 #include <linux/string.h>
0017 #include <linux/slab.h>
0018 #include <linux/delay.h>
0019 
0020 #include <media/dvb_frontend.h>
0021 #include "ves1x93.h"
0022 
0023 
0024 struct ves1x93_state {
0025     struct i2c_adapter* i2c;
0026     /* configuration settings */
0027     const struct ves1x93_config* config;
0028     struct dvb_frontend frontend;
0029 
0030     /* previous uncorrected block counter */
0031     enum fe_spectral_inversion inversion;
0032     u8 *init_1x93_tab;
0033     u8 *init_1x93_wtab;
0034     u8 tab_size;
0035     u8 demod_type;
0036     u32 frequency;
0037 };
0038 
0039 static int debug;
0040 #define dprintk if (debug) printk
0041 
0042 #define DEMOD_VES1893       0
0043 #define DEMOD_VES1993       1
0044 
0045 static u8 init_1893_tab [] = {
0046     0x01, 0xa4, 0x35, 0x80, 0x2a, 0x0b, 0x55, 0xc4,
0047     0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00,
0048     0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0049     0x80, 0x00, 0x21, 0xb0, 0x14, 0x00, 0xdc, 0x00,
0050     0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0051     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0052     0x00, 0x55, 0x00, 0x00, 0x7f, 0x00
0053 };
0054 
0055 static u8 init_1993_tab [] = {
0056     0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c,
0057     0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00,
0058     0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0059     0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10,
0060     0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0061     0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
0062     0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
0063     0x00, 0x00, 0x0e, 0x80, 0x00
0064 };
0065 
0066 static u8 init_1893_wtab[] =
0067 {
0068     1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
0069     0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1,
0070     1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
0071     1,1,1,0,1,1
0072 };
0073 
0074 static u8 init_1993_wtab[] =
0075 {
0076     1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
0077     0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1,
0078     1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
0079     1,1,1,0,1,1,1,1, 1,1,1,1,1
0080 };
0081 
0082 static int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data)
0083 {
0084     u8 buf [] = { 0x00, reg, data };
0085     struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 };
0086     int err;
0087 
0088     if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
0089         dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
0090         return -EREMOTEIO;
0091     }
0092 
0093     return 0;
0094 }
0095 
0096 static u8 ves1x93_readreg (struct ves1x93_state* state, u8 reg)
0097 {
0098     int ret;
0099     u8 b0 [] = { 0x00, reg };
0100     u8 b1 [] = { 0 };
0101     struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
0102                { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
0103 
0104     ret = i2c_transfer (state->i2c, msg, 2);
0105 
0106     if (ret != 2) return ret;
0107 
0108     return b1[0];
0109 }
0110 
0111 static int ves1x93_clr_bit (struct ves1x93_state* state)
0112 {
0113     msleep(10);
0114     ves1x93_writereg (state, 0, state->init_1x93_tab[0] & 0xfe);
0115     ves1x93_writereg (state, 0, state->init_1x93_tab[0]);
0116     msleep(50);
0117     return 0;
0118 }
0119 
0120 static int ves1x93_set_inversion(struct ves1x93_state *state,
0121                  enum fe_spectral_inversion inversion)
0122 {
0123     u8 val;
0124 
0125     /*
0126      * inversion on/off are interchanged because i and q seem to
0127      * be swapped on the hardware
0128      */
0129 
0130     switch (inversion) {
0131     case INVERSION_OFF:
0132         val = 0xc0;
0133         break;
0134     case INVERSION_ON:
0135         val = 0x80;
0136         break;
0137     case INVERSION_AUTO:
0138         val = 0x00;
0139         break;
0140     default:
0141         return -EINVAL;
0142     }
0143 
0144     return ves1x93_writereg (state, 0x0c, (state->init_1x93_tab[0x0c] & 0x3f) | val);
0145 }
0146 
0147 static int ves1x93_set_fec(struct ves1x93_state *state, enum fe_code_rate fec)
0148 {
0149     if (fec == FEC_AUTO)
0150         return ves1x93_writereg (state, 0x0d, 0x08);
0151     else if (fec < FEC_1_2 || fec > FEC_8_9)
0152         return -EINVAL;
0153     else
0154         return ves1x93_writereg (state, 0x0d, fec - FEC_1_2);
0155 }
0156 
0157 static enum fe_code_rate ves1x93_get_fec(struct ves1x93_state *state)
0158 {
0159     return FEC_1_2 + ((ves1x93_readreg (state, 0x0d) >> 4) & 0x7);
0160 }
0161 
0162 static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate)
0163 {
0164     u32 BDR;
0165     u32 ratio;
0166     u8  ADCONF, FCONF, FNR, AGCR;
0167     u32 BDRI;
0168     u32 tmp;
0169     u32 FIN;
0170 
0171     dprintk("%s: srate == %d\n", __func__, (unsigned int) srate);
0172 
0173     if (srate > state->config->xin/2)
0174         srate = state->config->xin/2;
0175 
0176     if (srate < 500000)
0177         srate = 500000;
0178 
0179 #define MUL (1UL<<26)
0180 
0181     FIN = (state->config->xin + 6000) >> 4;
0182 
0183     tmp = srate << 6;
0184     ratio = tmp / FIN;
0185 
0186     tmp = (tmp % FIN) << 8;
0187     ratio = (ratio << 8) + tmp / FIN;
0188 
0189     tmp = (tmp % FIN) << 8;
0190     ratio = (ratio << 8) + tmp / FIN;
0191 
0192     FNR = 0xff;
0193 
0194     if (ratio < MUL/3)       FNR = 0;
0195     if (ratio < (MUL*11)/50)     FNR = 1;
0196     if (ratio < MUL/6)       FNR = 2;
0197     if (ratio < MUL/9)       FNR = 3;
0198     if (ratio < MUL/12)      FNR = 4;
0199     if (ratio < (MUL*11)/200)    FNR = 5;
0200     if (ratio < MUL/24)      FNR = 6;
0201     if (ratio < (MUL*27)/1000)   FNR = 7;
0202     if (ratio < MUL/48)      FNR = 8;
0203     if (ratio < (MUL*137)/10000) FNR = 9;
0204 
0205     if (FNR == 0xff) {
0206         ADCONF = 0x89;
0207         FCONF  = 0x80;
0208         FNR = 0;
0209     } else {
0210         ADCONF = 0x81;
0211         FCONF  = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5);
0212         /*FCONF  = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/
0213     }
0214 
0215     BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1;
0216     BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1;
0217 
0218     dprintk("FNR= %d\n", FNR);
0219     dprintk("ratio= %08x\n", (unsigned int) ratio);
0220     dprintk("BDR= %08x\n", (unsigned int) BDR);
0221     dprintk("BDRI= %02x\n", (unsigned int) BDRI);
0222 
0223     if (BDRI > 0xff)
0224         BDRI = 0xff;
0225 
0226     ves1x93_writereg (state, 0x06, 0xff & BDR);
0227     ves1x93_writereg (state, 0x07, 0xff & (BDR >> 8));
0228     ves1x93_writereg (state, 0x08, 0x0f & (BDR >> 16));
0229 
0230     ves1x93_writereg (state, 0x09, BDRI);
0231     ves1x93_writereg (state, 0x20, ADCONF);
0232     ves1x93_writereg (state, 0x21, FCONF);
0233 
0234     AGCR = state->init_1x93_tab[0x05];
0235     if (state->config->invert_pwm)
0236         AGCR |= 0x20;
0237 
0238     if (srate < 6000000)
0239         AGCR |= 0x80;
0240     else
0241         AGCR &= ~0x80;
0242 
0243     ves1x93_writereg (state, 0x05, AGCR);
0244 
0245     /* ves1993 hates this, will lose lock */
0246     if (state->demod_type != DEMOD_VES1993)
0247         ves1x93_clr_bit (state);
0248 
0249     return 0;
0250 }
0251 
0252 static int ves1x93_init (struct dvb_frontend* fe)
0253 {
0254     struct ves1x93_state* state = fe->demodulator_priv;
0255     int i;
0256     int val;
0257 
0258     dprintk("%s: init chip\n", __func__);
0259 
0260     for (i = 0; i < state->tab_size; i++) {
0261         if (state->init_1x93_wtab[i]) {
0262             val = state->init_1x93_tab[i];
0263 
0264             if (state->config->invert_pwm && (i == 0x05)) val |= 0x20; /* invert PWM */
0265             ves1x93_writereg (state, i, val);
0266         }
0267     }
0268 
0269     return 0;
0270 }
0271 
0272 static int ves1x93_set_voltage(struct dvb_frontend *fe,
0273                    enum fe_sec_voltage voltage)
0274 {
0275     struct ves1x93_state* state = fe->demodulator_priv;
0276 
0277     switch (voltage) {
0278     case SEC_VOLTAGE_13:
0279         return ves1x93_writereg (state, 0x1f, 0x20);
0280     case SEC_VOLTAGE_18:
0281         return ves1x93_writereg (state, 0x1f, 0x30);
0282     case SEC_VOLTAGE_OFF:
0283         return ves1x93_writereg (state, 0x1f, 0x00);
0284     default:
0285         return -EINVAL;
0286     }
0287 }
0288 
0289 static int ves1x93_read_status(struct dvb_frontend *fe,
0290                    enum fe_status *status)
0291 {
0292     struct ves1x93_state* state = fe->demodulator_priv;
0293 
0294     u8 sync = ves1x93_readreg (state, 0x0e);
0295 
0296     /*
0297      * The ves1893 sometimes returns sync values that make no sense,
0298      * because, e.g., the SIGNAL bit is 0, while some of the higher
0299      * bits are 1 (and how can there be a CARRIER w/o a SIGNAL?).
0300      * Tests showed that the VITERBI and SYNC bits are returned
0301      * reliably, while the SIGNAL and CARRIER bits ar sometimes wrong.
0302      * If such a case occurs, we read the value again, until we get a
0303      * valid value.
0304      */
0305     int maxtry = 10; /* just for safety - let's not get stuck here */
0306     while ((sync & 0x03) != 0x03 && (sync & 0x0c) && maxtry--) {
0307         msleep(10);
0308         sync = ves1x93_readreg (state, 0x0e);
0309     }
0310 
0311     *status = 0;
0312 
0313     if (sync & 1)
0314         *status |= FE_HAS_SIGNAL;
0315 
0316     if (sync & 2)
0317         *status |= FE_HAS_CARRIER;
0318 
0319     if (sync & 4)
0320         *status |= FE_HAS_VITERBI;
0321 
0322     if (sync & 8)
0323         *status |= FE_HAS_SYNC;
0324 
0325     if ((sync & 0x1f) == 0x1f)
0326         *status |= FE_HAS_LOCK;
0327 
0328     return 0;
0329 }
0330 
0331 static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber)
0332 {
0333     struct ves1x93_state* state = fe->demodulator_priv;
0334 
0335     *ber = ves1x93_readreg (state, 0x15);
0336     *ber |= (ves1x93_readreg (state, 0x16) << 8);
0337     *ber |= ((ves1x93_readreg (state, 0x17) & 0x0F) << 16);
0338     *ber *= 10;
0339 
0340     return 0;
0341 }
0342 
0343 static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength)
0344 {
0345     struct ves1x93_state* state = fe->demodulator_priv;
0346 
0347     u8 signal = ~ves1x93_readreg (state, 0x0b);
0348     *strength = (signal << 8) | signal;
0349 
0350     return 0;
0351 }
0352 
0353 static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr)
0354 {
0355     struct ves1x93_state* state = fe->demodulator_priv;
0356 
0357     u8 _snr = ~ves1x93_readreg (state, 0x1c);
0358     *snr = (_snr << 8) | _snr;
0359 
0360     return 0;
0361 }
0362 
0363 static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
0364 {
0365     struct ves1x93_state* state = fe->demodulator_priv;
0366 
0367     *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f;
0368 
0369     if (*ucblocks == 0x7f)
0370         *ucblocks = 0xffffffff;   /* counter overflow... */
0371 
0372     ves1x93_writereg (state, 0x18, 0x00);  /* reset the counter */
0373     ves1x93_writereg (state, 0x18, 0x80);  /* dto. */
0374 
0375     return 0;
0376 }
0377 
0378 static int ves1x93_set_frontend(struct dvb_frontend *fe)
0379 {
0380     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0381     struct ves1x93_state* state = fe->demodulator_priv;
0382 
0383     if (fe->ops.tuner_ops.set_params) {
0384         fe->ops.tuner_ops.set_params(fe);
0385         if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
0386     }
0387     ves1x93_set_inversion (state, p->inversion);
0388     ves1x93_set_fec(state, p->fec_inner);
0389     ves1x93_set_symbolrate(state, p->symbol_rate);
0390     state->inversion = p->inversion;
0391     state->frequency = p->frequency;
0392 
0393     return 0;
0394 }
0395 
0396 static int ves1x93_get_frontend(struct dvb_frontend *fe,
0397                 struct dtv_frontend_properties *p)
0398 {
0399     struct ves1x93_state* state = fe->demodulator_priv;
0400     int afc;
0401 
0402     afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2;
0403     afc = (afc * (int)(p->symbol_rate/1000/8))/16;
0404 
0405     p->frequency = state->frequency - afc;
0406 
0407     /*
0408      * inversion indicator is only valid
0409      * if auto inversion was used
0410      */
0411     if (state->inversion == INVERSION_AUTO)
0412         p->inversion = (ves1x93_readreg (state, 0x0f) & 2) ?
0413                 INVERSION_OFF : INVERSION_ON;
0414     p->fec_inner = ves1x93_get_fec(state);
0415     /*  XXX FIXME: timing offset !! */
0416 
0417     return 0;
0418 }
0419 
0420 static int ves1x93_sleep(struct dvb_frontend* fe)
0421 {
0422     struct ves1x93_state* state = fe->demodulator_priv;
0423 
0424     return ves1x93_writereg (state, 0x00, 0x08);
0425 }
0426 
0427 static void ves1x93_release(struct dvb_frontend* fe)
0428 {
0429     struct ves1x93_state* state = fe->demodulator_priv;
0430     kfree(state);
0431 }
0432 
0433 static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
0434 {
0435     struct ves1x93_state* state = fe->demodulator_priv;
0436 
0437     if (enable) {
0438         return ves1x93_writereg(state, 0x00, 0x11);
0439     } else {
0440         return ves1x93_writereg(state, 0x00, 0x01);
0441     }
0442 }
0443 
0444 static const struct dvb_frontend_ops ves1x93_ops;
0445 
0446 struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
0447                     struct i2c_adapter* i2c)
0448 {
0449     struct ves1x93_state* state = NULL;
0450     u8 identity;
0451 
0452     /* allocate memory for the internal state */
0453     state = kzalloc(sizeof(struct ves1x93_state), GFP_KERNEL);
0454     if (state == NULL) goto error;
0455 
0456     /* setup the state */
0457     state->config = config;
0458     state->i2c = i2c;
0459     state->inversion = INVERSION_OFF;
0460 
0461     /* check if the demod is there + identify it */
0462     identity = ves1x93_readreg(state, 0x1e);
0463     switch (identity) {
0464     case 0xdc: /* VES1893A rev1 */
0465         printk("ves1x93: Detected ves1893a rev1\n");
0466         state->demod_type = DEMOD_VES1893;
0467         state->init_1x93_tab = init_1893_tab;
0468         state->init_1x93_wtab = init_1893_wtab;
0469         state->tab_size = sizeof(init_1893_tab);
0470         break;
0471 
0472     case 0xdd: /* VES1893A rev2 */
0473         printk("ves1x93: Detected ves1893a rev2\n");
0474         state->demod_type = DEMOD_VES1893;
0475         state->init_1x93_tab = init_1893_tab;
0476         state->init_1x93_wtab = init_1893_wtab;
0477         state->tab_size = sizeof(init_1893_tab);
0478         break;
0479 
0480     case 0xde: /* VES1993 */
0481         printk("ves1x93: Detected ves1993\n");
0482         state->demod_type = DEMOD_VES1993;
0483         state->init_1x93_tab = init_1993_tab;
0484         state->init_1x93_wtab = init_1993_wtab;
0485         state->tab_size = sizeof(init_1993_tab);
0486         break;
0487 
0488     default:
0489         goto error;
0490     }
0491 
0492     /* create dvb_frontend */
0493     memcpy(&state->frontend.ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops));
0494     state->frontend.demodulator_priv = state;
0495     return &state->frontend;
0496 
0497 error:
0498     kfree(state);
0499     return NULL;
0500 }
0501 
0502 static const struct dvb_frontend_ops ves1x93_ops = {
0503     .delsys = { SYS_DVBS },
0504     .info = {
0505         .name           = "VLSI VES1x93 DVB-S",
0506         .frequency_min_hz   =   950 * MHz,
0507         .frequency_max_hz   =  2150 * MHz,
0508         .frequency_stepsize_hz  =   125 * kHz,
0509         .frequency_tolerance_hz = 29500 * kHz,
0510         .symbol_rate_min    = 1000000,
0511         .symbol_rate_max    = 45000000,
0512     /*  .symbol_rate_tolerance  =   ???,*/
0513         .caps = FE_CAN_INVERSION_AUTO |
0514             FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
0515             FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
0516             FE_CAN_QPSK
0517     },
0518 
0519     .release = ves1x93_release,
0520 
0521     .init = ves1x93_init,
0522     .sleep = ves1x93_sleep,
0523     .i2c_gate_ctrl = ves1x93_i2c_gate_ctrl,
0524 
0525     .set_frontend = ves1x93_set_frontend,
0526     .get_frontend = ves1x93_get_frontend,
0527 
0528     .read_status = ves1x93_read_status,
0529     .read_ber = ves1x93_read_ber,
0530     .read_signal_strength = ves1x93_read_signal_strength,
0531     .read_snr = ves1x93_read_snr,
0532     .read_ucblocks = ves1x93_read_ucblocks,
0533 
0534     .set_voltage = ves1x93_set_voltage,
0535 };
0536 
0537 module_param(debug, int, 0644);
0538 
0539 MODULE_DESCRIPTION("VLSI VES1x93 DVB-S Demodulator driver");
0540 MODULE_AUTHOR("Ralph Metzler");
0541 MODULE_LICENSE("GPL");
0542 
0543 EXPORT_SYMBOL(ves1x93_attach);