1*0fcb8677SHans Verkuil // SPDX-License-Identifier: GPL-2.0-or-later 2*0fcb8677SHans Verkuil /* 3*0fcb8677SHans Verkuil Driver for Spase SP8870 demodulator 4*0fcb8677SHans Verkuil 5*0fcb8677SHans Verkuil Copyright (C) 1999 Juergen Peitz 6*0fcb8677SHans Verkuil 7*0fcb8677SHans Verkuil 8*0fcb8677SHans Verkuil */ 9*0fcb8677SHans Verkuil /* 10*0fcb8677SHans Verkuil * This driver needs external firmware. Please use the command 11*0fcb8677SHans Verkuil * "<kerneldir>/scripts/get_dvb_firmware alps_tdlb7" to 12*0fcb8677SHans Verkuil * download/extract it, and then copy it to /usr/lib/hotplug/firmware 13*0fcb8677SHans Verkuil * or /lib/firmware (depending on configuration of firmware hotplug). 14*0fcb8677SHans Verkuil */ 15*0fcb8677SHans Verkuil #define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw" 16*0fcb8677SHans Verkuil 17*0fcb8677SHans Verkuil #include <linux/init.h> 18*0fcb8677SHans Verkuil #include <linux/module.h> 19*0fcb8677SHans Verkuil #include <linux/device.h> 20*0fcb8677SHans Verkuil #include <linux/firmware.h> 21*0fcb8677SHans Verkuil #include <linux/delay.h> 22*0fcb8677SHans Verkuil #include <linux/string.h> 23*0fcb8677SHans Verkuil #include <linux/slab.h> 24*0fcb8677SHans Verkuil 25*0fcb8677SHans Verkuil #include <media/dvb_frontend.h> 26*0fcb8677SHans Verkuil #include "sp8870.h" 27*0fcb8677SHans Verkuil 28*0fcb8677SHans Verkuil 29*0fcb8677SHans Verkuil struct sp8870_state { 30*0fcb8677SHans Verkuil 31*0fcb8677SHans Verkuil struct i2c_adapter* i2c; 32*0fcb8677SHans Verkuil 33*0fcb8677SHans Verkuil const struct sp8870_config* config; 34*0fcb8677SHans Verkuil 35*0fcb8677SHans Verkuil struct dvb_frontend frontend; 36*0fcb8677SHans Verkuil 37*0fcb8677SHans Verkuil /* demodulator private data */ 38*0fcb8677SHans Verkuil u8 initialised:1; 39*0fcb8677SHans Verkuil }; 40*0fcb8677SHans Verkuil 41*0fcb8677SHans Verkuil static int debug; 42*0fcb8677SHans Verkuil #define dprintk(args...) \ 43*0fcb8677SHans Verkuil do { \ 44*0fcb8677SHans Verkuil if (debug) printk(KERN_DEBUG "sp8870: " args); \ 45*0fcb8677SHans Verkuil } while (0) 46*0fcb8677SHans Verkuil 47*0fcb8677SHans Verkuil /* firmware size for sp8870 */ 48*0fcb8677SHans Verkuil #define SP8870_FIRMWARE_SIZE 16382 49*0fcb8677SHans Verkuil 50*0fcb8677SHans Verkuil /* starting point for firmware in file 'Sc_main.mc' */ 51*0fcb8677SHans Verkuil #define SP8870_FIRMWARE_OFFSET 0x0A 52*0fcb8677SHans Verkuil 53*0fcb8677SHans Verkuil static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data) 54*0fcb8677SHans Verkuil { 55*0fcb8677SHans Verkuil u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff }; 56*0fcb8677SHans Verkuil struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 }; 57*0fcb8677SHans Verkuil int err; 58*0fcb8677SHans Verkuil 59*0fcb8677SHans Verkuil if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { 60*0fcb8677SHans Verkuil dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data); 61*0fcb8677SHans Verkuil return -EREMOTEIO; 62*0fcb8677SHans Verkuil } 63*0fcb8677SHans Verkuil 64*0fcb8677SHans Verkuil return 0; 65*0fcb8677SHans Verkuil } 66*0fcb8677SHans Verkuil 67*0fcb8677SHans Verkuil static int sp8870_readreg (struct sp8870_state* state, u16 reg) 68*0fcb8677SHans Verkuil { 69*0fcb8677SHans Verkuil int ret; 70*0fcb8677SHans Verkuil u8 b0 [] = { reg >> 8 , reg & 0xff }; 71*0fcb8677SHans Verkuil u8 b1 [] = { 0, 0 }; 72*0fcb8677SHans Verkuil struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 }, 73*0fcb8677SHans Verkuil { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; 74*0fcb8677SHans Verkuil 75*0fcb8677SHans Verkuil ret = i2c_transfer (state->i2c, msg, 2); 76*0fcb8677SHans Verkuil 77*0fcb8677SHans Verkuil if (ret != 2) { 78*0fcb8677SHans Verkuil dprintk("%s: readreg error (ret == %i)\n", __func__, ret); 79*0fcb8677SHans Verkuil return -1; 80*0fcb8677SHans Verkuil } 81*0fcb8677SHans Verkuil 82*0fcb8677SHans Verkuil return (b1[0] << 8 | b1[1]); 83*0fcb8677SHans Verkuil } 84*0fcb8677SHans Verkuil 85*0fcb8677SHans Verkuil static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw) 86*0fcb8677SHans Verkuil { 87*0fcb8677SHans Verkuil struct i2c_msg msg; 88*0fcb8677SHans Verkuil const char *fw_buf = fw->data; 89*0fcb8677SHans Verkuil int fw_pos; 90*0fcb8677SHans Verkuil u8 tx_buf[255]; 91*0fcb8677SHans Verkuil int tx_len; 92*0fcb8677SHans Verkuil int err = 0; 93*0fcb8677SHans Verkuil 94*0fcb8677SHans Verkuil dprintk ("%s: ...\n", __func__); 95*0fcb8677SHans Verkuil 96*0fcb8677SHans Verkuil if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET) 97*0fcb8677SHans Verkuil return -EINVAL; 98*0fcb8677SHans Verkuil 99*0fcb8677SHans Verkuil // system controller stop 100*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0F00, 0x0000); 101*0fcb8677SHans Verkuil 102*0fcb8677SHans Verkuil // instruction RAM register hiword 103*0fcb8677SHans Verkuil sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF)); 104*0fcb8677SHans Verkuil 105*0fcb8677SHans Verkuil // instruction RAM MWR 106*0fcb8677SHans Verkuil sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16)); 107*0fcb8677SHans Verkuil 108*0fcb8677SHans Verkuil // do firmware upload 109*0fcb8677SHans Verkuil fw_pos = SP8870_FIRMWARE_OFFSET; 110*0fcb8677SHans Verkuil while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){ 111*0fcb8677SHans Verkuil tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos; 112*0fcb8677SHans Verkuil // write register 0xCF0A 113*0fcb8677SHans Verkuil tx_buf[0] = 0xCF; 114*0fcb8677SHans Verkuil tx_buf[1] = 0x0A; 115*0fcb8677SHans Verkuil memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len); 116*0fcb8677SHans Verkuil msg.addr = state->config->demod_address; 117*0fcb8677SHans Verkuil msg.flags = 0; 118*0fcb8677SHans Verkuil msg.buf = tx_buf; 119*0fcb8677SHans Verkuil msg.len = tx_len + 2; 120*0fcb8677SHans Verkuil if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { 121*0fcb8677SHans Verkuil printk("%s: firmware upload failed!\n", __func__); 122*0fcb8677SHans Verkuil printk ("%s: i2c error (err == %i)\n", __func__, err); 123*0fcb8677SHans Verkuil return err; 124*0fcb8677SHans Verkuil } 125*0fcb8677SHans Verkuil fw_pos += tx_len; 126*0fcb8677SHans Verkuil } 127*0fcb8677SHans Verkuil 128*0fcb8677SHans Verkuil dprintk ("%s: done!\n", __func__); 129*0fcb8677SHans Verkuil return 0; 130*0fcb8677SHans Verkuil }; 131*0fcb8677SHans Verkuil 132*0fcb8677SHans Verkuil static void sp8870_microcontroller_stop (struct sp8870_state* state) 133*0fcb8677SHans Verkuil { 134*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0F08, 0x000); 135*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0F09, 0x000); 136*0fcb8677SHans Verkuil 137*0fcb8677SHans Verkuil // microcontroller STOP 138*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0F00, 0x000); 139*0fcb8677SHans Verkuil } 140*0fcb8677SHans Verkuil 141*0fcb8677SHans Verkuil static void sp8870_microcontroller_start (struct sp8870_state* state) 142*0fcb8677SHans Verkuil { 143*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0F08, 0x000); 144*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0F09, 0x000); 145*0fcb8677SHans Verkuil 146*0fcb8677SHans Verkuil // microcontroller START 147*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0F00, 0x001); 148*0fcb8677SHans Verkuil // not documented but if we don't read 0x0D01 out here 149*0fcb8677SHans Verkuil // we don't get a correct data valid signal 150*0fcb8677SHans Verkuil sp8870_readreg(state, 0x0D01); 151*0fcb8677SHans Verkuil } 152*0fcb8677SHans Verkuil 153*0fcb8677SHans Verkuil static int sp8870_read_data_valid_signal(struct sp8870_state* state) 154*0fcb8677SHans Verkuil { 155*0fcb8677SHans Verkuil return (sp8870_readreg(state, 0x0D02) > 0); 156*0fcb8677SHans Verkuil } 157*0fcb8677SHans Verkuil 158*0fcb8677SHans Verkuil static int configure_reg0xc05 (struct dtv_frontend_properties *p, u16 *reg0xc05) 159*0fcb8677SHans Verkuil { 160*0fcb8677SHans Verkuil int known_parameters = 1; 161*0fcb8677SHans Verkuil 162*0fcb8677SHans Verkuil *reg0xc05 = 0x000; 163*0fcb8677SHans Verkuil 164*0fcb8677SHans Verkuil switch (p->modulation) { 165*0fcb8677SHans Verkuil case QPSK: 166*0fcb8677SHans Verkuil break; 167*0fcb8677SHans Verkuil case QAM_16: 168*0fcb8677SHans Verkuil *reg0xc05 |= (1 << 10); 169*0fcb8677SHans Verkuil break; 170*0fcb8677SHans Verkuil case QAM_64: 171*0fcb8677SHans Verkuil *reg0xc05 |= (2 << 10); 172*0fcb8677SHans Verkuil break; 173*0fcb8677SHans Verkuil case QAM_AUTO: 174*0fcb8677SHans Verkuil known_parameters = 0; 175*0fcb8677SHans Verkuil break; 176*0fcb8677SHans Verkuil default: 177*0fcb8677SHans Verkuil return -EINVAL; 178*0fcb8677SHans Verkuil } 179*0fcb8677SHans Verkuil 180*0fcb8677SHans Verkuil switch (p->hierarchy) { 181*0fcb8677SHans Verkuil case HIERARCHY_NONE: 182*0fcb8677SHans Verkuil break; 183*0fcb8677SHans Verkuil case HIERARCHY_1: 184*0fcb8677SHans Verkuil *reg0xc05 |= (1 << 7); 185*0fcb8677SHans Verkuil break; 186*0fcb8677SHans Verkuil case HIERARCHY_2: 187*0fcb8677SHans Verkuil *reg0xc05 |= (2 << 7); 188*0fcb8677SHans Verkuil break; 189*0fcb8677SHans Verkuil case HIERARCHY_4: 190*0fcb8677SHans Verkuil *reg0xc05 |= (3 << 7); 191*0fcb8677SHans Verkuil break; 192*0fcb8677SHans Verkuil case HIERARCHY_AUTO: 193*0fcb8677SHans Verkuil known_parameters = 0; 194*0fcb8677SHans Verkuil break; 195*0fcb8677SHans Verkuil default: 196*0fcb8677SHans Verkuil return -EINVAL; 197*0fcb8677SHans Verkuil } 198*0fcb8677SHans Verkuil 199*0fcb8677SHans Verkuil switch (p->code_rate_HP) { 200*0fcb8677SHans Verkuil case FEC_1_2: 201*0fcb8677SHans Verkuil break; 202*0fcb8677SHans Verkuil case FEC_2_3: 203*0fcb8677SHans Verkuil *reg0xc05 |= (1 << 3); 204*0fcb8677SHans Verkuil break; 205*0fcb8677SHans Verkuil case FEC_3_4: 206*0fcb8677SHans Verkuil *reg0xc05 |= (2 << 3); 207*0fcb8677SHans Verkuil break; 208*0fcb8677SHans Verkuil case FEC_5_6: 209*0fcb8677SHans Verkuil *reg0xc05 |= (3 << 3); 210*0fcb8677SHans Verkuil break; 211*0fcb8677SHans Verkuil case FEC_7_8: 212*0fcb8677SHans Verkuil *reg0xc05 |= (4 << 3); 213*0fcb8677SHans Verkuil break; 214*0fcb8677SHans Verkuil case FEC_AUTO: 215*0fcb8677SHans Verkuil known_parameters = 0; 216*0fcb8677SHans Verkuil break; 217*0fcb8677SHans Verkuil default: 218*0fcb8677SHans Verkuil return -EINVAL; 219*0fcb8677SHans Verkuil } 220*0fcb8677SHans Verkuil 221*0fcb8677SHans Verkuil if (known_parameters) 222*0fcb8677SHans Verkuil *reg0xc05 |= (2 << 1); /* use specified parameters */ 223*0fcb8677SHans Verkuil else 224*0fcb8677SHans Verkuil *reg0xc05 |= (1 << 1); /* enable autoprobing */ 225*0fcb8677SHans Verkuil 226*0fcb8677SHans Verkuil return 0; 227*0fcb8677SHans Verkuil } 228*0fcb8677SHans Verkuil 229*0fcb8677SHans Verkuil static int sp8870_wake_up(struct sp8870_state* state) 230*0fcb8677SHans Verkuil { 231*0fcb8677SHans Verkuil // enable TS output and interface pins 232*0fcb8677SHans Verkuil return sp8870_writereg(state, 0xC18, 0x00D); 233*0fcb8677SHans Verkuil } 234*0fcb8677SHans Verkuil 235*0fcb8677SHans Verkuil static int sp8870_set_frontend_parameters(struct dvb_frontend *fe) 236*0fcb8677SHans Verkuil { 237*0fcb8677SHans Verkuil struct dtv_frontend_properties *p = &fe->dtv_property_cache; 238*0fcb8677SHans Verkuil struct sp8870_state* state = fe->demodulator_priv; 239*0fcb8677SHans Verkuil int err; 240*0fcb8677SHans Verkuil u16 reg0xc05; 241*0fcb8677SHans Verkuil 242*0fcb8677SHans Verkuil if ((err = configure_reg0xc05(p, ®0xc05))) 243*0fcb8677SHans Verkuil return err; 244*0fcb8677SHans Verkuil 245*0fcb8677SHans Verkuil // system controller stop 246*0fcb8677SHans Verkuil sp8870_microcontroller_stop(state); 247*0fcb8677SHans Verkuil 248*0fcb8677SHans Verkuil // set tuner parameters 249*0fcb8677SHans Verkuil if (fe->ops.tuner_ops.set_params) { 250*0fcb8677SHans Verkuil fe->ops.tuner_ops.set_params(fe); 251*0fcb8677SHans Verkuil if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); 252*0fcb8677SHans Verkuil } 253*0fcb8677SHans Verkuil 254*0fcb8677SHans Verkuil // sample rate correction bit [23..17] 255*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0319, 0x000A); 256*0fcb8677SHans Verkuil 257*0fcb8677SHans Verkuil // sample rate correction bit [16..0] 258*0fcb8677SHans Verkuil sp8870_writereg(state, 0x031A, 0x0AAB); 259*0fcb8677SHans Verkuil 260*0fcb8677SHans Verkuil // integer carrier offset 261*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0309, 0x0400); 262*0fcb8677SHans Verkuil 263*0fcb8677SHans Verkuil // fractional carrier offset 264*0fcb8677SHans Verkuil sp8870_writereg(state, 0x030A, 0x0000); 265*0fcb8677SHans Verkuil 266*0fcb8677SHans Verkuil // filter for 6/7/8 Mhz channel 267*0fcb8677SHans Verkuil if (p->bandwidth_hz == 6000000) 268*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0311, 0x0002); 269*0fcb8677SHans Verkuil else if (p->bandwidth_hz == 7000000) 270*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0311, 0x0001); 271*0fcb8677SHans Verkuil else 272*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0311, 0x0000); 273*0fcb8677SHans Verkuil 274*0fcb8677SHans Verkuil // scan order: 2k first = 0x0000, 8k first = 0x0001 275*0fcb8677SHans Verkuil if (p->transmission_mode == TRANSMISSION_MODE_2K) 276*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0338, 0x0000); 277*0fcb8677SHans Verkuil else 278*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0338, 0x0001); 279*0fcb8677SHans Verkuil 280*0fcb8677SHans Verkuil sp8870_writereg(state, 0xc05, reg0xc05); 281*0fcb8677SHans Verkuil 282*0fcb8677SHans Verkuil // read status reg in order to clear pending irqs 283*0fcb8677SHans Verkuil err = sp8870_readreg(state, 0x200); 284*0fcb8677SHans Verkuil if (err < 0) 285*0fcb8677SHans Verkuil return err; 286*0fcb8677SHans Verkuil 287*0fcb8677SHans Verkuil // system controller start 288*0fcb8677SHans Verkuil sp8870_microcontroller_start(state); 289*0fcb8677SHans Verkuil 290*0fcb8677SHans Verkuil return 0; 291*0fcb8677SHans Verkuil } 292*0fcb8677SHans Verkuil 293*0fcb8677SHans Verkuil static int sp8870_init (struct dvb_frontend* fe) 294*0fcb8677SHans Verkuil { 295*0fcb8677SHans Verkuil struct sp8870_state* state = fe->demodulator_priv; 296*0fcb8677SHans Verkuil const struct firmware *fw = NULL; 297*0fcb8677SHans Verkuil 298*0fcb8677SHans Verkuil sp8870_wake_up(state); 299*0fcb8677SHans Verkuil if (state->initialised) return 0; 300*0fcb8677SHans Verkuil state->initialised = 1; 301*0fcb8677SHans Verkuil 302*0fcb8677SHans Verkuil dprintk ("%s\n", __func__); 303*0fcb8677SHans Verkuil 304*0fcb8677SHans Verkuil 305*0fcb8677SHans Verkuil /* request the firmware, this will block until someone uploads it */ 306*0fcb8677SHans Verkuil printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE); 307*0fcb8677SHans Verkuil if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) { 308*0fcb8677SHans Verkuil printk("sp8870: no firmware upload (timeout or file not found?)\n"); 309*0fcb8677SHans Verkuil return -EIO; 310*0fcb8677SHans Verkuil } 311*0fcb8677SHans Verkuil 312*0fcb8677SHans Verkuil if (sp8870_firmware_upload(state, fw)) { 313*0fcb8677SHans Verkuil printk("sp8870: writing firmware to device failed\n"); 314*0fcb8677SHans Verkuil release_firmware(fw); 315*0fcb8677SHans Verkuil return -EIO; 316*0fcb8677SHans Verkuil } 317*0fcb8677SHans Verkuil release_firmware(fw); 318*0fcb8677SHans Verkuil printk("sp8870: firmware upload complete\n"); 319*0fcb8677SHans Verkuil 320*0fcb8677SHans Verkuil /* enable TS output and interface pins */ 321*0fcb8677SHans Verkuil sp8870_writereg(state, 0xc18, 0x00d); 322*0fcb8677SHans Verkuil 323*0fcb8677SHans Verkuil // system controller stop 324*0fcb8677SHans Verkuil sp8870_microcontroller_stop(state); 325*0fcb8677SHans Verkuil 326*0fcb8677SHans Verkuil // ADC mode 327*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0301, 0x0003); 328*0fcb8677SHans Verkuil 329*0fcb8677SHans Verkuil // Reed Solomon parity bytes passed to output 330*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0C13, 0x0001); 331*0fcb8677SHans Verkuil 332*0fcb8677SHans Verkuil // MPEG clock is suppressed if no valid data 333*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0C14, 0x0001); 334*0fcb8677SHans Verkuil 335*0fcb8677SHans Verkuil /* bit 0x010: enable data valid signal */ 336*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0D00, 0x010); 337*0fcb8677SHans Verkuil sp8870_writereg(state, 0x0D01, 0x000); 338*0fcb8677SHans Verkuil 339*0fcb8677SHans Verkuil return 0; 340*0fcb8677SHans Verkuil } 341*0fcb8677SHans Verkuil 342*0fcb8677SHans Verkuil static int sp8870_read_status(struct dvb_frontend *fe, 343*0fcb8677SHans Verkuil enum fe_status *fe_status) 344*0fcb8677SHans Verkuil { 345*0fcb8677SHans Verkuil struct sp8870_state* state = fe->demodulator_priv; 346*0fcb8677SHans Verkuil int status; 347*0fcb8677SHans Verkuil int signal; 348*0fcb8677SHans Verkuil 349*0fcb8677SHans Verkuil *fe_status = 0; 350*0fcb8677SHans Verkuil 351*0fcb8677SHans Verkuil status = sp8870_readreg (state, 0x0200); 352*0fcb8677SHans Verkuil if (status < 0) 353*0fcb8677SHans Verkuil return -EIO; 354*0fcb8677SHans Verkuil 355*0fcb8677SHans Verkuil signal = sp8870_readreg (state, 0x0303); 356*0fcb8677SHans Verkuil if (signal < 0) 357*0fcb8677SHans Verkuil return -EIO; 358*0fcb8677SHans Verkuil 359*0fcb8677SHans Verkuil if (signal > 0x0F) 360*0fcb8677SHans Verkuil *fe_status |= FE_HAS_SIGNAL; 361*0fcb8677SHans Verkuil if (status & 0x08) 362*0fcb8677SHans Verkuil *fe_status |= FE_HAS_SYNC; 363*0fcb8677SHans Verkuil if (status & 0x04) 364*0fcb8677SHans Verkuil *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI; 365*0fcb8677SHans Verkuil 366*0fcb8677SHans Verkuil return 0; 367*0fcb8677SHans Verkuil } 368*0fcb8677SHans Verkuil 369*0fcb8677SHans Verkuil static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber) 370*0fcb8677SHans Verkuil { 371*0fcb8677SHans Verkuil struct sp8870_state* state = fe->demodulator_priv; 372*0fcb8677SHans Verkuil int ret; 373*0fcb8677SHans Verkuil u32 tmp; 374*0fcb8677SHans Verkuil 375*0fcb8677SHans Verkuil *ber = 0; 376*0fcb8677SHans Verkuil 377*0fcb8677SHans Verkuil ret = sp8870_readreg(state, 0xC08); 378*0fcb8677SHans Verkuil if (ret < 0) 379*0fcb8677SHans Verkuil return -EIO; 380*0fcb8677SHans Verkuil 381*0fcb8677SHans Verkuil tmp = ret & 0x3F; 382*0fcb8677SHans Verkuil 383*0fcb8677SHans Verkuil ret = sp8870_readreg(state, 0xC07); 384*0fcb8677SHans Verkuil if (ret < 0) 385*0fcb8677SHans Verkuil return -EIO; 386*0fcb8677SHans Verkuil 387*0fcb8677SHans Verkuil tmp = ret << 6; 388*0fcb8677SHans Verkuil if (tmp >= 0x3FFF0) 389*0fcb8677SHans Verkuil tmp = ~0; 390*0fcb8677SHans Verkuil 391*0fcb8677SHans Verkuil *ber = tmp; 392*0fcb8677SHans Verkuil 393*0fcb8677SHans Verkuil return 0; 394*0fcb8677SHans Verkuil } 395*0fcb8677SHans Verkuil 396*0fcb8677SHans Verkuil static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal) 397*0fcb8677SHans Verkuil { 398*0fcb8677SHans Verkuil struct sp8870_state* state = fe->demodulator_priv; 399*0fcb8677SHans Verkuil int ret; 400*0fcb8677SHans Verkuil u16 tmp; 401*0fcb8677SHans Verkuil 402*0fcb8677SHans Verkuil *signal = 0; 403*0fcb8677SHans Verkuil 404*0fcb8677SHans Verkuil ret = sp8870_readreg (state, 0x306); 405*0fcb8677SHans Verkuil if (ret < 0) 406*0fcb8677SHans Verkuil return -EIO; 407*0fcb8677SHans Verkuil 408*0fcb8677SHans Verkuil tmp = ret << 8; 409*0fcb8677SHans Verkuil 410*0fcb8677SHans Verkuil ret = sp8870_readreg (state, 0x303); 411*0fcb8677SHans Verkuil if (ret < 0) 412*0fcb8677SHans Verkuil return -EIO; 413*0fcb8677SHans Verkuil 414*0fcb8677SHans Verkuil tmp |= ret; 415*0fcb8677SHans Verkuil 416*0fcb8677SHans Verkuil if (tmp) 417*0fcb8677SHans Verkuil *signal = 0xFFFF - tmp; 418*0fcb8677SHans Verkuil 419*0fcb8677SHans Verkuil return 0; 420*0fcb8677SHans Verkuil } 421*0fcb8677SHans Verkuil 422*0fcb8677SHans Verkuil static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks) 423*0fcb8677SHans Verkuil { 424*0fcb8677SHans Verkuil struct sp8870_state* state = fe->demodulator_priv; 425*0fcb8677SHans Verkuil int ret; 426*0fcb8677SHans Verkuil 427*0fcb8677SHans Verkuil *ublocks = 0; 428*0fcb8677SHans Verkuil 429*0fcb8677SHans Verkuil ret = sp8870_readreg(state, 0xC0C); 430*0fcb8677SHans Verkuil if (ret < 0) 431*0fcb8677SHans Verkuil return -EIO; 432*0fcb8677SHans Verkuil 433*0fcb8677SHans Verkuil if (ret == 0xFFFF) 434*0fcb8677SHans Verkuil ret = ~0; 435*0fcb8677SHans Verkuil 436*0fcb8677SHans Verkuil *ublocks = ret; 437*0fcb8677SHans Verkuil 438*0fcb8677SHans Verkuil return 0; 439*0fcb8677SHans Verkuil } 440*0fcb8677SHans Verkuil 441*0fcb8677SHans Verkuil /* number of trials to recover from lockup */ 442*0fcb8677SHans Verkuil #define MAXTRIALS 5 443*0fcb8677SHans Verkuil /* maximum checks for data valid signal */ 444*0fcb8677SHans Verkuil #define MAXCHECKS 100 445*0fcb8677SHans Verkuil 446*0fcb8677SHans Verkuil /* only for debugging: counter for detected lockups */ 447*0fcb8677SHans Verkuil static int lockups; 448*0fcb8677SHans Verkuil /* only for debugging: counter for channel switches */ 449*0fcb8677SHans Verkuil static int switches; 450*0fcb8677SHans Verkuil 451*0fcb8677SHans Verkuil static int sp8870_set_frontend(struct dvb_frontend *fe) 452*0fcb8677SHans Verkuil { 453*0fcb8677SHans Verkuil struct dtv_frontend_properties *p = &fe->dtv_property_cache; 454*0fcb8677SHans Verkuil struct sp8870_state* state = fe->demodulator_priv; 455*0fcb8677SHans Verkuil 456*0fcb8677SHans Verkuil /* 457*0fcb8677SHans Verkuil The firmware of the sp8870 sometimes locks up after setting frontend parameters. 458*0fcb8677SHans Verkuil We try to detect this by checking the data valid signal. 459*0fcb8677SHans Verkuil If it is not set after MAXCHECKS we try to recover the lockup by setting 460*0fcb8677SHans Verkuil the frontend parameters again. 461*0fcb8677SHans Verkuil */ 462*0fcb8677SHans Verkuil 463*0fcb8677SHans Verkuil int err = 0; 464*0fcb8677SHans Verkuil int valid = 0; 465*0fcb8677SHans Verkuil int trials = 0; 466*0fcb8677SHans Verkuil int check_count = 0; 467*0fcb8677SHans Verkuil 468*0fcb8677SHans Verkuil dprintk("%s: frequency = %i\n", __func__, p->frequency); 469*0fcb8677SHans Verkuil 470*0fcb8677SHans Verkuil for (trials = 1; trials <= MAXTRIALS; trials++) { 471*0fcb8677SHans Verkuil 472*0fcb8677SHans Verkuil err = sp8870_set_frontend_parameters(fe); 473*0fcb8677SHans Verkuil if (err) 474*0fcb8677SHans Verkuil return err; 475*0fcb8677SHans Verkuil 476*0fcb8677SHans Verkuil for (check_count = 0; check_count < MAXCHECKS; check_count++) { 477*0fcb8677SHans Verkuil // valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0); 478*0fcb8677SHans Verkuil valid = sp8870_read_data_valid_signal(state); 479*0fcb8677SHans Verkuil if (valid) { 480*0fcb8677SHans Verkuil dprintk("%s: delay = %i usec\n", 481*0fcb8677SHans Verkuil __func__, check_count * 10); 482*0fcb8677SHans Verkuil break; 483*0fcb8677SHans Verkuil } 484*0fcb8677SHans Verkuil udelay(10); 485*0fcb8677SHans Verkuil } 486*0fcb8677SHans Verkuil if (valid) 487*0fcb8677SHans Verkuil break; 488*0fcb8677SHans Verkuil } 489*0fcb8677SHans Verkuil 490*0fcb8677SHans Verkuil if (!valid) { 491*0fcb8677SHans Verkuil printk("%s: firmware crash!!!!!!\n", __func__); 492*0fcb8677SHans Verkuil return -EIO; 493*0fcb8677SHans Verkuil } 494*0fcb8677SHans Verkuil 495*0fcb8677SHans Verkuil if (debug) { 496*0fcb8677SHans Verkuil if (valid) { 497*0fcb8677SHans Verkuil if (trials > 1) { 498*0fcb8677SHans Verkuil printk("%s: firmware lockup!!!\n", __func__); 499*0fcb8677SHans Verkuil printk("%s: recovered after %i trial(s))\n", __func__, trials - 1); 500*0fcb8677SHans Verkuil lockups++; 501*0fcb8677SHans Verkuil } 502*0fcb8677SHans Verkuil } 503*0fcb8677SHans Verkuil switches++; 504*0fcb8677SHans Verkuil printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups); 505*0fcb8677SHans Verkuil } 506*0fcb8677SHans Verkuil 507*0fcb8677SHans Verkuil return 0; 508*0fcb8677SHans Verkuil } 509*0fcb8677SHans Verkuil 510*0fcb8677SHans Verkuil static int sp8870_sleep(struct dvb_frontend* fe) 511*0fcb8677SHans Verkuil { 512*0fcb8677SHans Verkuil struct sp8870_state* state = fe->demodulator_priv; 513*0fcb8677SHans Verkuil 514*0fcb8677SHans Verkuil // tristate TS output and disable interface pins 515*0fcb8677SHans Verkuil return sp8870_writereg(state, 0xC18, 0x000); 516*0fcb8677SHans Verkuil } 517*0fcb8677SHans Verkuil 518*0fcb8677SHans Verkuil static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) 519*0fcb8677SHans Verkuil { 520*0fcb8677SHans Verkuil fesettings->min_delay_ms = 350; 521*0fcb8677SHans Verkuil fesettings->step_size = 0; 522*0fcb8677SHans Verkuil fesettings->max_drift = 0; 523*0fcb8677SHans Verkuil return 0; 524*0fcb8677SHans Verkuil } 525*0fcb8677SHans Verkuil 526*0fcb8677SHans Verkuil static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) 527*0fcb8677SHans Verkuil { 528*0fcb8677SHans Verkuil struct sp8870_state* state = fe->demodulator_priv; 529*0fcb8677SHans Verkuil 530*0fcb8677SHans Verkuil if (enable) { 531*0fcb8677SHans Verkuil return sp8870_writereg(state, 0x206, 0x001); 532*0fcb8677SHans Verkuil } else { 533*0fcb8677SHans Verkuil return sp8870_writereg(state, 0x206, 0x000); 534*0fcb8677SHans Verkuil } 535*0fcb8677SHans Verkuil } 536*0fcb8677SHans Verkuil 537*0fcb8677SHans Verkuil static void sp8870_release(struct dvb_frontend* fe) 538*0fcb8677SHans Verkuil { 539*0fcb8677SHans Verkuil struct sp8870_state* state = fe->demodulator_priv; 540*0fcb8677SHans Verkuil kfree(state); 541*0fcb8677SHans Verkuil } 542*0fcb8677SHans Verkuil 543*0fcb8677SHans Verkuil static const struct dvb_frontend_ops sp8870_ops; 544*0fcb8677SHans Verkuil 545*0fcb8677SHans Verkuil struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, 546*0fcb8677SHans Verkuil struct i2c_adapter* i2c) 547*0fcb8677SHans Verkuil { 548*0fcb8677SHans Verkuil struct sp8870_state* state = NULL; 549*0fcb8677SHans Verkuil 550*0fcb8677SHans Verkuil /* allocate memory for the internal state */ 551*0fcb8677SHans Verkuil state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL); 552*0fcb8677SHans Verkuil if (state == NULL) goto error; 553*0fcb8677SHans Verkuil 554*0fcb8677SHans Verkuil /* setup the state */ 555*0fcb8677SHans Verkuil state->config = config; 556*0fcb8677SHans Verkuil state->i2c = i2c; 557*0fcb8677SHans Verkuil state->initialised = 0; 558*0fcb8677SHans Verkuil 559*0fcb8677SHans Verkuil /* check if the demod is there */ 560*0fcb8677SHans Verkuil if (sp8870_readreg(state, 0x0200) < 0) goto error; 561*0fcb8677SHans Verkuil 562*0fcb8677SHans Verkuil /* create dvb_frontend */ 563*0fcb8677SHans Verkuil memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops)); 564*0fcb8677SHans Verkuil state->frontend.demodulator_priv = state; 565*0fcb8677SHans Verkuil return &state->frontend; 566*0fcb8677SHans Verkuil 567*0fcb8677SHans Verkuil error: 568*0fcb8677SHans Verkuil kfree(state); 569*0fcb8677SHans Verkuil return NULL; 570*0fcb8677SHans Verkuil } 571*0fcb8677SHans Verkuil 572*0fcb8677SHans Verkuil static const struct dvb_frontend_ops sp8870_ops = { 573*0fcb8677SHans Verkuil .delsys = { SYS_DVBT }, 574*0fcb8677SHans Verkuil .info = { 575*0fcb8677SHans Verkuil .name = "Spase SP8870 DVB-T", 576*0fcb8677SHans Verkuil .frequency_min_hz = 470 * MHz, 577*0fcb8677SHans Verkuil .frequency_max_hz = 860 * MHz, 578*0fcb8677SHans Verkuil .frequency_stepsize_hz = 166666, 579*0fcb8677SHans Verkuil .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | 580*0fcb8677SHans Verkuil FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | 581*0fcb8677SHans Verkuil FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 582*0fcb8677SHans Verkuil FE_CAN_QPSK | FE_CAN_QAM_16 | 583*0fcb8677SHans Verkuil FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 584*0fcb8677SHans Verkuil FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER 585*0fcb8677SHans Verkuil }, 586*0fcb8677SHans Verkuil 587*0fcb8677SHans Verkuil .release = sp8870_release, 588*0fcb8677SHans Verkuil 589*0fcb8677SHans Verkuil .init = sp8870_init, 590*0fcb8677SHans Verkuil .sleep = sp8870_sleep, 591*0fcb8677SHans Verkuil .i2c_gate_ctrl = sp8870_i2c_gate_ctrl, 592*0fcb8677SHans Verkuil 593*0fcb8677SHans Verkuil .set_frontend = sp8870_set_frontend, 594*0fcb8677SHans Verkuil .get_tune_settings = sp8870_get_tune_settings, 595*0fcb8677SHans Verkuil 596*0fcb8677SHans Verkuil .read_status = sp8870_read_status, 597*0fcb8677SHans Verkuil .read_ber = sp8870_read_ber, 598*0fcb8677SHans Verkuil .read_signal_strength = sp8870_read_signal_strength, 599*0fcb8677SHans Verkuil .read_ucblocks = sp8870_read_uncorrected_blocks, 600*0fcb8677SHans Verkuil }; 601*0fcb8677SHans Verkuil 602*0fcb8677SHans Verkuil module_param(debug, int, 0644); 603*0fcb8677SHans Verkuil MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); 604*0fcb8677SHans Verkuil 605*0fcb8677SHans Verkuil MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver"); 606*0fcb8677SHans Verkuil MODULE_AUTHOR("Juergen Peitz"); 607*0fcb8677SHans Verkuil MODULE_LICENSE("GPL"); 608*0fcb8677SHans Verkuil 609*0fcb8677SHans Verkuil EXPORT_SYMBOL(sp8870_attach); 610