46 #include <linux/kernel.h>
47 #include <linux/module.h>
48 #include <linux/string.h>
49 #include <linux/slab.h>
51 #include <asm/div64.h>
71 #define STATUS_UCBLOCKS 1
74 static int debug_legacy_dish_switch;
75 #define dprintk(args...) \
77 if (debug) printk(KERN_DEBUG "stv0299: " args); \
90 dprintk(
"%s: writereg error (reg == 0x%02x, val == 0x%02x, "
91 "ret == %i)\n", __func__, reg, data, ret);
103 return stv0299_writeregI(state, buf[0], buf[1]);
111 struct i2c_msg msg [] = { { .addr = state->
config->demod_address, .flags = 0, .buf = b0, .len = 1 },
112 { .addr = state->
config->demod_address, .flags =
I2C_M_RD, .buf = b1, .len = 1 } };
117 dprintk(
"%s: readreg error (reg == 0x%02x, ret == %i)\n",
126 struct i2c_msg msg [] = { { .
addr = state->
config->demod_address, .flags = 0, .buf = &
reg1, .len = 1 },
127 { .addr = state->
config->demod_address, .flags =
I2C_M_RD, .buf =
b, .len = len } };
132 dprintk(
"%s: readreg error (ret == %i)\n", __func__, ret);
134 return ret == 2 ? 0 :
ret;
144 return stv0299_writeregI (state, 0x31, 0x1f);
148 return stv0299_writeregI (state, 0x31, 0x01);
152 return stv0299_writeregI (state, 0x31, 0x02);
156 return stv0299_writeregI (state, 0x31, 0x04);
160 return stv0299_writeregI (state, 0x31, 0x08);
164 return stv0299_writeregI (state, 0x31, 0x10);
181 index = stv0299_readreg (state, 0x1b);
187 return fec_tab [
index];
190 static int stv0299_wait_diseqc_fifo (
struct stv0299_state* state,
int timeout)
196 while (stv0299_readreg(state, 0x0a) & 1) {
197 if (jiffies - start > timeout) {
198 dprintk (
"%s: timeout!!\n", __func__);
207 static int stv0299_wait_diseqc_idle (
struct stv0299_state* state,
int timeout)
213 while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) {
214 if (jiffies - start > timeout) {
215 dprintk (
"%s: timeout!!\n", __func__);
231 if ((srate < 1000000) || (srate > 45000000))
return -
EINVAL;
235 big += (state->
config->mclk-1);
239 return state->
config->set_symbol_rate(fe, srate, ratio);
242 static int stv0299_get_symbolrate (
struct stv0299_state* state)
252 stv0299_readregs (state, 0x1f, sfr, 3);
253 stv0299_readregs (state, 0x1a, (
u8 *)&rtf, 1);
255 srate = (sfr[0] << 8) | sfr[1];
258 srate += (sfr[2] >> 4) * Mclk / 256;
259 offset = (
s32) rtf * (srate / 4096L);
262 dprintk (
"%s : srate = %i\n", __func__, srate);
263 dprintk (
"%s : ofset = %i\n", __func__, offset);
274 static int stv0299_send_diseqc_msg (
struct dvb_frontend* fe,
283 if (stv0299_wait_diseqc_idle (state, 100) < 0)
286 val = stv0299_readreg (state, 0x08);
288 if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x6))
292 if (stv0299_wait_diseqc_fifo (state, 100) < 0)
295 if (stv0299_writeregI (state, 0x09, m->
msg[i]))
299 if (stv0299_wait_diseqc_idle (state, 100) < 0)
312 if (stv0299_wait_diseqc_idle (state, 100) < 0)
315 val = stv0299_readreg (state, 0x08);
317 if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x2))
320 if (stv0299_writeregI (state, 0x09, burst ==
SEC_MINI_A ? 0x00 : 0xff))
323 if (stv0299_wait_diseqc_idle (state, 100) < 0)
326 if (stv0299_writeregI (state, 0x08, val))
337 if (stv0299_wait_diseqc_idle (state, 100) < 0)
340 val = stv0299_readreg (state, 0x08);
344 return stv0299_writeregI (state, 0x08, val | 0x3);
347 return stv0299_writeregI (state, 0x08, (val & ~0x3) | 0x02);
364 reg0x08 = stv0299_readreg (state, 0x08);
365 reg0x0c = stv0299_readreg (state, 0x0c);
371 reg0x08 = (reg0x08 & 0x3f) | (state->
config->lock_output << 6);
392 if (state->
config->op0_off)
395 stv0299_writeregI(state, 0x08, reg0x08);
396 return stv0299_writeregI(state, 0x0c, reg0x0c);
399 static int stv0299_send_legacy_dish_cmd (
struct dvb_frontend* fe,
unsigned long cmd)
410 reg0x08 = stv0299_readreg (state, 0x08);
411 reg0x0c = stv0299_readreg (state, 0x0c);
413 stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->
config->lock_output << 6));
418 if (debug_legacy_dish_switch)
419 printk (
"%s switch command: 0x%04lx\n",__func__, cmd);
422 if (debug_legacy_dish_switch)
424 stv0299_writeregI (state, 0x0c, reg0x0c | 0x50);
428 for (i=0; i<9; i++) {
429 if (debug_legacy_dish_switch)
431 if((cmd & 0x01) != last) {
433 stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50));
434 last = (last) ? 0 : 1;
442 if (debug_legacy_dish_switch) {
443 printk (
"%s(%d): switch delay (should be 32k followed by all 8k\n",
444 __func__, fe->
dvb->num);
445 for (i = 1; i < 10; i++)
459 dprintk(
"stv0299: init chip\n");
461 stv0299_writeregI(state, 0x02, 0x30 | state->
mcr_reg);
464 for (i = 0; ; i += 2) {
465 reg = state->
config->inittab[
i];
466 val = state->
config->inittab[i+1];
467 if (reg == 0xff && val == 0xff)
469 if (reg == 0x0c && state->
config->op0_off)
473 stv0299_writeregI(state, reg, val);
483 u8 signal = 0xff - stv0299_readreg (state, 0x18);
484 u8 sync = stv0299_readreg (state, 0x1b);
486 dprintk (
"%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
501 if ((sync & 0x98) == 0x98)
514 *ber = stv0299_readreg(state, 0x1e) | (stv0299_readreg(state, 0x1d) << 8);
519 static int stv0299_read_signal_strength(
struct dvb_frontend* fe,
u16* strength)
523 s32 signal = 0xffff - ((stv0299_readreg (state, 0x18) << 8)
524 | stv0299_readreg (state, 0x19));
526 dprintk (
"%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __func__,
527 stv0299_readreg (state, 0x18),
528 stv0299_readreg (state, 0x19), (
int) signal);
530 signal = signal * 5 / 4;
531 *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
540 s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8)
541 | stv0299_readreg (state, 0x25));
542 xsnr = 3 * (xsnr - 0xa100);
543 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
555 state->
ucblocks += stv0299_readreg(state, 0x1e);
556 state->
ucblocks += (stv0299_readreg(state, 0x1d) << 8);
562 static int stv0299_set_frontend(
struct dvb_frontend *fe)
568 dprintk (
"%s : FE_SET_FRONTEND\n", __func__);
569 if (state->
config->set_ts_params)
570 state->
config->set_ts_params(fe, 0);
576 printk(
"stv0299 does not support auto-inversion\n");
579 if (state->
config->invert) invval = (~invval) & 1;
580 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
582 if (fe->
ops.tuner_ops.set_params) {
583 fe->
ops.tuner_ops.set_params(fe);
584 if (fe->
ops.i2c_gate_ctrl) fe->
ops.i2c_gate_ctrl(fe, 0);
589 stv0299_writeregI(state, 0x22, 0x00);
590 stv0299_writeregI(state, 0x23, 0x00);
599 static int stv0299_get_frontend(
struct dvb_frontend *fe)
606 derot_freq = (
s32)(
s16) ((stv0299_readreg (state, 0x22) << 8)
607 | stv0299_readreg (state, 0x23));
609 derot_freq *= (state->
config->mclk >> 16);
615 invval = stv0299_readreg (state, 0x0c) & 1;
616 if (state->
config->invert) invval = (~invval) & 1;
629 stv0299_writeregI(state, 0x02, 0xb0 | state->
mcr_reg);
640 stv0299_writeregI(state, 0x05, 0xb5);
642 stv0299_writeregI(state, 0x05, 0x35);
692 stv0299_writeregI(state, 0x02, 0x30);
694 id = stv0299_readreg(state, 0x00);
698 if (
id != 0xa1 &&
id != 0x80)
goto error;
713 .name =
"ST STV0299 DVB-S",
714 .frequency_min = 950000,
715 .frequency_max = 2150000,
716 .frequency_stepsize = 125,
717 .frequency_tolerance = 0,
718 .symbol_rate_min = 1000000,
719 .symbol_rate_max = 45000000,
720 .symbol_rate_tolerance = 500,
727 .release = stv0299_release,
729 .init = stv0299_init,
730 .sleep = stv0299_sleep,
731 .write = stv0299_write,
732 .i2c_gate_ctrl = stv0299_i2c_gate_ctrl,
734 .set_frontend = stv0299_set_frontend,
735 .get_frontend = stv0299_get_frontend,
736 .get_tune_settings = stv0299_get_tune_settings,
738 .read_status = stv0299_read_status,
739 .read_ber = stv0299_read_ber,
740 .read_signal_strength = stv0299_read_signal_strength,
741 .read_snr = stv0299_read_snr,
742 .read_ucblocks = stv0299_read_ucblocks,
744 .diseqc_send_master_cmd = stv0299_send_diseqc_msg,
745 .diseqc_send_burst = stv0299_send_diseqc_burst,
746 .set_tone = stv0299_set_tone,
747 .set_voltage = stv0299_set_voltage,
748 .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd,
752 MODULE_PARM_DESC(debug_legacy_dish_switch,
"Enable timing analysis for Dish Network legacy switches");
758 MODULE_AUTHOR(
"Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, "
759 "Andreas Oberritter, Andrew de Quincey, Kenneth Aafly");