Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003     Driver for Spase SP8870 demodulator
0004 
0005     Copyright (C) 1999 Juergen Peitz
0006 
0007 
0008 */
0009 /*
0010  * This driver needs external firmware. Please use the command
0011  * "<kerneldir>/scripts/get_dvb_firmware alps_tdlb7" to
0012  * download/extract it, and then copy it to /usr/lib/hotplug/firmware
0013  * or /lib/firmware (depending on configuration of firmware hotplug).
0014  */
0015 #define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw"
0016 
0017 #include <linux/init.h>
0018 #include <linux/module.h>
0019 #include <linux/device.h>
0020 #include <linux/firmware.h>
0021 #include <linux/delay.h>
0022 #include <linux/string.h>
0023 #include <linux/slab.h>
0024 
0025 #include <media/dvb_frontend.h>
0026 #include "sp8870.h"
0027 
0028 
0029 struct sp8870_state {
0030 
0031     struct i2c_adapter* i2c;
0032 
0033     const struct sp8870_config* config;
0034 
0035     struct dvb_frontend frontend;
0036 
0037     /* demodulator private data */
0038     u8 initialised:1;
0039 };
0040 
0041 static int debug;
0042 #define dprintk(args...) \
0043     do { \
0044         if (debug) printk(KERN_DEBUG "sp8870: " args); \
0045     } while (0)
0046 
0047 /* firmware size for sp8870 */
0048 #define SP8870_FIRMWARE_SIZE 16382
0049 
0050 /* starting point for firmware in file 'Sc_main.mc' */
0051 #define SP8870_FIRMWARE_OFFSET 0x0A
0052 
0053 static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
0054 {
0055     u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
0056     struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 };
0057     int err;
0058 
0059     if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
0060         dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
0061         return -EREMOTEIO;
0062     }
0063 
0064     return 0;
0065 }
0066 
0067 static int sp8870_readreg (struct sp8870_state* state, u16 reg)
0068 {
0069     int ret;
0070     u8 b0 [] = { reg >> 8 , reg & 0xff };
0071     u8 b1 [] = { 0, 0 };
0072     struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
0073                { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
0074 
0075     ret = i2c_transfer (state->i2c, msg, 2);
0076 
0077     if (ret != 2) {
0078         dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
0079         return -1;
0080     }
0081 
0082     return (b1[0] << 8 | b1[1]);
0083 }
0084 
0085 static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw)
0086 {
0087     struct i2c_msg msg;
0088     const char *fw_buf = fw->data;
0089     int fw_pos;
0090     u8 tx_buf[255];
0091     int tx_len;
0092     int err = 0;
0093 
0094     dprintk ("%s: ...\n", __func__);
0095 
0096     if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET)
0097         return -EINVAL;
0098 
0099     // system controller stop
0100     sp8870_writereg(state, 0x0F00, 0x0000);
0101 
0102     // instruction RAM register hiword
0103     sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF));
0104 
0105     // instruction RAM MWR
0106     sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16));
0107 
0108     // do firmware upload
0109     fw_pos = SP8870_FIRMWARE_OFFSET;
0110     while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){
0111         tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos;
0112         // write register 0xCF0A
0113         tx_buf[0] = 0xCF;
0114         tx_buf[1] = 0x0A;
0115         memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len);
0116         msg.addr = state->config->demod_address;
0117         msg.flags = 0;
0118         msg.buf = tx_buf;
0119         msg.len = tx_len + 2;
0120         if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
0121             printk("%s: firmware upload failed!\n", __func__);
0122             printk ("%s: i2c error (err == %i)\n", __func__, err);
0123             return err;
0124         }
0125         fw_pos += tx_len;
0126     }
0127 
0128     dprintk ("%s: done!\n", __func__);
0129     return 0;
0130 };
0131 
0132 static void sp8870_microcontroller_stop (struct sp8870_state* state)
0133 {
0134     sp8870_writereg(state, 0x0F08, 0x000);
0135     sp8870_writereg(state, 0x0F09, 0x000);
0136 
0137     // microcontroller STOP
0138     sp8870_writereg(state, 0x0F00, 0x000);
0139 }
0140 
0141 static void sp8870_microcontroller_start (struct sp8870_state* state)
0142 {
0143     sp8870_writereg(state, 0x0F08, 0x000);
0144     sp8870_writereg(state, 0x0F09, 0x000);
0145 
0146     // microcontroller START
0147     sp8870_writereg(state, 0x0F00, 0x001);
0148     // not documented but if we don't read 0x0D01 out here
0149     // we don't get a correct data valid signal
0150     sp8870_readreg(state, 0x0D01);
0151 }
0152 
0153 static int sp8870_read_data_valid_signal(struct sp8870_state* state)
0154 {
0155     return (sp8870_readreg(state, 0x0D02) > 0);
0156 }
0157 
0158 static int configure_reg0xc05 (struct dtv_frontend_properties *p, u16 *reg0xc05)
0159 {
0160     int known_parameters = 1;
0161 
0162     *reg0xc05 = 0x000;
0163 
0164     switch (p->modulation) {
0165     case QPSK:
0166         break;
0167     case QAM_16:
0168         *reg0xc05 |= (1 << 10);
0169         break;
0170     case QAM_64:
0171         *reg0xc05 |= (2 << 10);
0172         break;
0173     case QAM_AUTO:
0174         known_parameters = 0;
0175         break;
0176     default:
0177         return -EINVAL;
0178     }
0179 
0180     switch (p->hierarchy) {
0181     case HIERARCHY_NONE:
0182         break;
0183     case HIERARCHY_1:
0184         *reg0xc05 |= (1 << 7);
0185         break;
0186     case HIERARCHY_2:
0187         *reg0xc05 |= (2 << 7);
0188         break;
0189     case HIERARCHY_4:
0190         *reg0xc05 |= (3 << 7);
0191         break;
0192     case HIERARCHY_AUTO:
0193         known_parameters = 0;
0194         break;
0195     default:
0196         return -EINVAL;
0197     }
0198 
0199     switch (p->code_rate_HP) {
0200     case FEC_1_2:
0201         break;
0202     case FEC_2_3:
0203         *reg0xc05 |= (1 << 3);
0204         break;
0205     case FEC_3_4:
0206         *reg0xc05 |= (2 << 3);
0207         break;
0208     case FEC_5_6:
0209         *reg0xc05 |= (3 << 3);
0210         break;
0211     case FEC_7_8:
0212         *reg0xc05 |= (4 << 3);
0213         break;
0214     case FEC_AUTO:
0215         known_parameters = 0;
0216         break;
0217     default:
0218         return -EINVAL;
0219     }
0220 
0221     if (known_parameters)
0222         *reg0xc05 |= (2 << 1);  /* use specified parameters */
0223     else
0224         *reg0xc05 |= (1 << 1);  /* enable autoprobing */
0225 
0226     return 0;
0227 }
0228 
0229 static int sp8870_wake_up(struct sp8870_state* state)
0230 {
0231     // enable TS output and interface pins
0232     return sp8870_writereg(state, 0xC18, 0x00D);
0233 }
0234 
0235 static int sp8870_set_frontend_parameters(struct dvb_frontend *fe)
0236 {
0237     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0238     struct sp8870_state* state = fe->demodulator_priv;
0239     int  err;
0240     u16 reg0xc05;
0241 
0242     if ((err = configure_reg0xc05(p, &reg0xc05)))
0243         return err;
0244 
0245     // system controller stop
0246     sp8870_microcontroller_stop(state);
0247 
0248     // set tuner parameters
0249     if (fe->ops.tuner_ops.set_params) {
0250         fe->ops.tuner_ops.set_params(fe);
0251         if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
0252     }
0253 
0254     // sample rate correction bit [23..17]
0255     sp8870_writereg(state, 0x0319, 0x000A);
0256 
0257     // sample rate correction bit [16..0]
0258     sp8870_writereg(state, 0x031A, 0x0AAB);
0259 
0260     // integer carrier offset
0261     sp8870_writereg(state, 0x0309, 0x0400);
0262 
0263     // fractional carrier offset
0264     sp8870_writereg(state, 0x030A, 0x0000);
0265 
0266     // filter for 6/7/8 Mhz channel
0267     if (p->bandwidth_hz == 6000000)
0268         sp8870_writereg(state, 0x0311, 0x0002);
0269     else if (p->bandwidth_hz == 7000000)
0270         sp8870_writereg(state, 0x0311, 0x0001);
0271     else
0272         sp8870_writereg(state, 0x0311, 0x0000);
0273 
0274     // scan order: 2k first = 0x0000, 8k first = 0x0001
0275     if (p->transmission_mode == TRANSMISSION_MODE_2K)
0276         sp8870_writereg(state, 0x0338, 0x0000);
0277     else
0278         sp8870_writereg(state, 0x0338, 0x0001);
0279 
0280     sp8870_writereg(state, 0xc05, reg0xc05);
0281 
0282     // read status reg in order to clear pending irqs
0283     err = sp8870_readreg(state, 0x200);
0284     if (err < 0)
0285         return err;
0286 
0287     // system controller start
0288     sp8870_microcontroller_start(state);
0289 
0290     return 0;
0291 }
0292 
0293 static int sp8870_init (struct dvb_frontend* fe)
0294 {
0295     struct sp8870_state* state = fe->demodulator_priv;
0296     const struct firmware *fw = NULL;
0297 
0298     sp8870_wake_up(state);
0299     if (state->initialised) return 0;
0300     state->initialised = 1;
0301 
0302     dprintk ("%s\n", __func__);
0303 
0304 
0305     /* request the firmware, this will block until someone uploads it */
0306     printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
0307     if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
0308         printk("sp8870: no firmware upload (timeout or file not found?)\n");
0309         return -EIO;
0310     }
0311 
0312     if (sp8870_firmware_upload(state, fw)) {
0313         printk("sp8870: writing firmware to device failed\n");
0314         release_firmware(fw);
0315         return -EIO;
0316     }
0317     release_firmware(fw);
0318     printk("sp8870: firmware upload complete\n");
0319 
0320     /* enable TS output and interface pins */
0321     sp8870_writereg(state, 0xc18, 0x00d);
0322 
0323     // system controller stop
0324     sp8870_microcontroller_stop(state);
0325 
0326     // ADC mode
0327     sp8870_writereg(state, 0x0301, 0x0003);
0328 
0329     // Reed Solomon parity bytes passed to output
0330     sp8870_writereg(state, 0x0C13, 0x0001);
0331 
0332     // MPEG clock is suppressed if no valid data
0333     sp8870_writereg(state, 0x0C14, 0x0001);
0334 
0335     /* bit 0x010: enable data valid signal */
0336     sp8870_writereg(state, 0x0D00, 0x010);
0337     sp8870_writereg(state, 0x0D01, 0x000);
0338 
0339     return 0;
0340 }
0341 
0342 static int sp8870_read_status(struct dvb_frontend *fe,
0343                   enum fe_status *fe_status)
0344 {
0345     struct sp8870_state* state = fe->demodulator_priv;
0346     int status;
0347     int signal;
0348 
0349     *fe_status = 0;
0350 
0351     status = sp8870_readreg (state, 0x0200);
0352     if (status < 0)
0353         return -EIO;
0354 
0355     signal = sp8870_readreg (state, 0x0303);
0356     if (signal < 0)
0357         return -EIO;
0358 
0359     if (signal > 0x0F)
0360         *fe_status |= FE_HAS_SIGNAL;
0361     if (status & 0x08)
0362         *fe_status |= FE_HAS_SYNC;
0363     if (status & 0x04)
0364         *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI;
0365 
0366     return 0;
0367 }
0368 
0369 static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
0370 {
0371     struct sp8870_state* state = fe->demodulator_priv;
0372     int ret;
0373     u32 tmp;
0374 
0375     *ber = 0;
0376 
0377     ret = sp8870_readreg(state, 0xC08);
0378     if (ret < 0)
0379         return -EIO;
0380 
0381     tmp = ret & 0x3F;
0382 
0383     ret = sp8870_readreg(state, 0xC07);
0384     if (ret < 0)
0385         return -EIO;
0386 
0387     tmp = ret << 6;
0388     if (tmp >= 0x3FFF0)
0389         tmp = ~0;
0390 
0391     *ber = tmp;
0392 
0393     return 0;
0394 }
0395 
0396 static int sp8870_read_signal_strength(struct dvb_frontend* fe,  u16 * signal)
0397 {
0398     struct sp8870_state* state = fe->demodulator_priv;
0399     int ret;
0400     u16 tmp;
0401 
0402     *signal = 0;
0403 
0404     ret = sp8870_readreg (state, 0x306);
0405     if (ret < 0)
0406         return -EIO;
0407 
0408     tmp = ret << 8;
0409 
0410     ret = sp8870_readreg (state, 0x303);
0411     if (ret < 0)
0412         return -EIO;
0413 
0414     tmp |= ret;
0415 
0416     if (tmp)
0417         *signal = 0xFFFF - tmp;
0418 
0419     return 0;
0420 }
0421 
0422 static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
0423 {
0424     struct sp8870_state* state = fe->demodulator_priv;
0425     int ret;
0426 
0427     *ublocks = 0;
0428 
0429     ret = sp8870_readreg(state, 0xC0C);
0430     if (ret < 0)
0431         return -EIO;
0432 
0433     if (ret == 0xFFFF)
0434         ret = ~0;
0435 
0436     *ublocks = ret;
0437 
0438     return 0;
0439 }
0440 
0441 /* number of trials to recover from lockup */
0442 #define MAXTRIALS 5
0443 /* maximum checks for data valid signal */
0444 #define MAXCHECKS 100
0445 
0446 /* only for debugging: counter for detected lockups */
0447 static int lockups;
0448 /* only for debugging: counter for channel switches */
0449 static int switches;
0450 
0451 static int sp8870_set_frontend(struct dvb_frontend *fe)
0452 {
0453     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0454     struct sp8870_state* state = fe->demodulator_priv;
0455 
0456     /*
0457         The firmware of the sp8870 sometimes locks up after setting frontend parameters.
0458         We try to detect this by checking the data valid signal.
0459         If it is not set after MAXCHECKS we try to recover the lockup by setting
0460         the frontend parameters again.
0461     */
0462 
0463     int err = 0;
0464     int valid = 0;
0465     int trials = 0;
0466     int check_count = 0;
0467 
0468     dprintk("%s: frequency = %i\n", __func__, p->frequency);
0469 
0470     for (trials = 1; trials <= MAXTRIALS; trials++) {
0471 
0472         err = sp8870_set_frontend_parameters(fe);
0473         if (err)
0474             return err;
0475 
0476         for (check_count = 0; check_count < MAXCHECKS; check_count++) {
0477 //          valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
0478             valid = sp8870_read_data_valid_signal(state);
0479             if (valid) {
0480                 dprintk("%s: delay = %i usec\n",
0481                     __func__, check_count * 10);
0482                 break;
0483             }
0484             udelay(10);
0485         }
0486         if (valid)
0487             break;
0488     }
0489 
0490     if (!valid) {
0491         printk("%s: firmware crash!!!!!!\n", __func__);
0492         return -EIO;
0493     }
0494 
0495     if (debug) {
0496         if (valid) {
0497             if (trials > 1) {
0498                 printk("%s: firmware lockup!!!\n", __func__);
0499                 printk("%s: recovered after %i trial(s))\n",  __func__, trials - 1);
0500                 lockups++;
0501             }
0502         }
0503         switches++;
0504         printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups);
0505     }
0506 
0507     return 0;
0508 }
0509 
0510 static int sp8870_sleep(struct dvb_frontend* fe)
0511 {
0512     struct sp8870_state* state = fe->demodulator_priv;
0513 
0514     // tristate TS output and disable interface pins
0515     return sp8870_writereg(state, 0xC18, 0x000);
0516 }
0517 
0518 static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
0519 {
0520     fesettings->min_delay_ms = 350;
0521     fesettings->step_size = 0;
0522     fesettings->max_drift = 0;
0523     return 0;
0524 }
0525 
0526 static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
0527 {
0528     struct sp8870_state* state = fe->demodulator_priv;
0529 
0530     if (enable) {
0531         return sp8870_writereg(state, 0x206, 0x001);
0532     } else {
0533         return sp8870_writereg(state, 0x206, 0x000);
0534     }
0535 }
0536 
0537 static void sp8870_release(struct dvb_frontend* fe)
0538 {
0539     struct sp8870_state* state = fe->demodulator_priv;
0540     kfree(state);
0541 }
0542 
0543 static const struct dvb_frontend_ops sp8870_ops;
0544 
0545 struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
0546                    struct i2c_adapter* i2c)
0547 {
0548     struct sp8870_state* state = NULL;
0549 
0550     /* allocate memory for the internal state */
0551     state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL);
0552     if (state == NULL) goto error;
0553 
0554     /* setup the state */
0555     state->config = config;
0556     state->i2c = i2c;
0557     state->initialised = 0;
0558 
0559     /* check if the demod is there */
0560     if (sp8870_readreg(state, 0x0200) < 0) goto error;
0561 
0562     /* create dvb_frontend */
0563     memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
0564     state->frontend.demodulator_priv = state;
0565     return &state->frontend;
0566 
0567 error:
0568     kfree(state);
0569     return NULL;
0570 }
0571 
0572 static const struct dvb_frontend_ops sp8870_ops = {
0573     .delsys = { SYS_DVBT },
0574     .info = {
0575         .name           = "Spase SP8870 DVB-T",
0576         .frequency_min_hz   = 470 * MHz,
0577         .frequency_max_hz   = 860 * MHz,
0578         .frequency_stepsize_hz  = 166666,
0579         .caps           = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
0580                       FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
0581                       FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
0582                       FE_CAN_QPSK | FE_CAN_QAM_16 |
0583                       FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
0584                       FE_CAN_HIERARCHY_AUTO |  FE_CAN_RECOVER
0585     },
0586 
0587     .release = sp8870_release,
0588 
0589     .init = sp8870_init,
0590     .sleep = sp8870_sleep,
0591     .i2c_gate_ctrl = sp8870_i2c_gate_ctrl,
0592 
0593     .set_frontend = sp8870_set_frontend,
0594     .get_tune_settings = sp8870_get_tune_settings,
0595 
0596     .read_status = sp8870_read_status,
0597     .read_ber = sp8870_read_ber,
0598     .read_signal_strength = sp8870_read_signal_strength,
0599     .read_ucblocks = sp8870_read_uncorrected_blocks,
0600 };
0601 
0602 module_param(debug, int, 0644);
0603 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
0604 
0605 MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
0606 MODULE_AUTHOR("Juergen Peitz");
0607 MODULE_LICENSE("GPL");
0608 
0609 EXPORT_SYMBOL(sp8870_attach);