0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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);
0132 stv0288_writeregI(state, 0x29, 0);
0133 stv0288_writeregI(state, 0x2a, 0);
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);
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))
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))
0191 return -EREMOTEIO;
0192 break;
0193
0194 case SEC_TONE_OFF:
0195 if (stv0288_writeregI(state, 0x05, 0x12))
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
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
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
0468 stv0288_writeregI(state, 0x15, 0xc5);
0469
0470 tda[2] = 0x0;
0471 for (tm = -9; tm < 7;) {
0472
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,
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
0561 state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
0562 if (state == NULL)
0563 goto error;
0564
0565
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
0580 if (id != 0x11)
0581 goto error;
0582
0583
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