12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/string.h>
15 #include <linux/slab.h>
17 #include <asm/div64.h>
22 #define REVISION_REG 0x00
23 #define SYSTEM_MODE_REG 0x01
24 #define TS_CTRL_REG_1 0x02
25 #define TS_CTRL_REG_2 0x03
26 #define PIN_CTRL_REG_1 0x04
27 #define PIN_CTRL_REG_2 0x05
28 #define LOCK_STATUS_REG_1 0x0f
29 #define LOCK_STATUS_REG_2 0x10
30 #define ACQ_STATUS_REG 0x11
31 #define ACQ_CTRL_REG_1 0x13
32 #define ACQ_CTRL_REG_2 0x14
33 #define PLL_DIVISOR_REG 0x15
34 #define COARSE_TUNE_REG 0x16
35 #define FINE_TUNE_REG_L 0x17
36 #define FINE_TUNE_REG_H 0x18
38 #define ANALOG_AGC_POWER_LEVEL_REG 0x28
39 #define CFO_ESTIMATOR_CTRL_REG_1 0x29
40 #define CFO_ESTIMATOR_CTRL_REG_2 0x2a
41 #define CFO_ESTIMATOR_CTRL_REG_3 0x2b
43 #define SYM_RATE_ESTIMATE_REG_L 0x31
44 #define SYM_RATE_ESTIMATE_REG_M 0x32
45 #define SYM_RATE_ESTIMATE_REG_H 0x33
47 #define CFO_ESTIMATOR_OFFSET_REG_L 0x36
48 #define CFO_ESTIMATOR_OFFSET_REG_H 0x37
49 #define CFO_ERROR_REG_L 0x38
50 #define CFO_ERROR_REG_H 0x39
51 #define SYM_RATE_ESTIMATOR_CTRL_REG 0x3a
53 #define SYM_RATE_REG_L 0x3f
54 #define SYM_RATE_REG_M 0x40
55 #define SYM_RATE_REG_H 0x41
56 #define SYM_RATE_ESTIMATOR_MAXIMUM_REG 0x42
57 #define SYM_RATE_ESTIMATOR_MINIMUM_REG 0x43
59 #define C_N_ESTIMATOR_CTRL_REG 0x7c
60 #define C_N_ESTIMATOR_THRSHLD_REG 0x7d
61 #define C_N_ESTIMATOR_LEVEL_REG_L 0x7e
62 #define C_N_ESTIMATOR_LEVEL_REG_H 0x7f
64 #define BLIND_SCAN_CTRL_REG 0x80
66 #define LSA_CTRL_REG_1 0x8D
67 #define SPCTRM_TILT_CORR_THRSHLD_REG 0x8f
68 #define ONE_DB_BNDWDTH_THRSHLD_REG 0x90
69 #define TWO_DB_BNDWDTH_THRSHLD_REG 0x91
70 #define THREE_DB_BNDWDTH_THRSHLD_REG 0x92
71 #define INBAND_POWER_THRSHLD_REG 0x93
72 #define REF_NOISE_LVL_MRGN_THRSHLD_REG 0x94
74 #define VIT_SRCH_CTRL_REG_1 0xa0
75 #define VIT_SRCH_CTRL_REG_2 0xa1
76 #define VIT_SRCH_CTRL_REG_3 0xa2
77 #define VIT_SRCH_STATUS_REG 0xa3
78 #define VITERBI_BER_COUNT_REG_L 0xab
79 #define REED_SOLOMON_CTRL_REG 0xb0
80 #define REED_SOLOMON_ERROR_COUNT_REG_L 0xb1
81 #define PRBS_CTRL_REG 0xb5
83 #define LNB_CTRL_REG_1 0xc0
84 #define LNB_CTRL_REG_2 0xc1
85 #define LNB_CTRL_REG_3 0xc2
86 #define LNB_CTRL_REG_4 0xc3
87 #define LNB_CTRL_STATUS_REG 0xc4
88 #define LNB_FIFO_REGS_0 0xc5
89 #define LNB_FIFO_REGS_1 0xc6
90 #define LNB_FIFO_REGS_2 0xc7
91 #define LNB_FIFO_REGS_3 0xc8
92 #define LNB_FIFO_REGS_4 0xc9
93 #define LNB_FIFO_REGS_5 0xca
94 #define LNB_SUPPLY_CTRL_REG_1 0xcb
95 #define LNB_SUPPLY_CTRL_REG_2 0xcc
96 #define LNB_SUPPLY_CTRL_REG_3 0xcd
97 #define LNB_SUPPLY_CTRL_REG_4 0xce
98 #define LNB_SUPPLY_STATUS_REG 0xcf
103 #define ALLOWABLE_FS_COUNT 10
105 #define STATUS_UCBLOCKS 1
108 #define dprintk(args...) \
111 printk(KERN_DEBUG "si21xx: " args); \
149 static u8 serit_sp1511lhb_inittab[] = {
233 .addr = state->
config->demod_address,
245 dprintk(
"%s: writereg error (reg1 == 0x%02x, data == 0x%02x, "
246 "ret == %i)\n", __func__, reg1, data[0], ret);
254 u8 buf[] = {
reg, data };
265 dprintk(
"%s: writereg error (reg == 0x%02x, data == 0x%02x, "
266 "ret == %i)\n", __func__, reg, data, ret);
271 static int si21_write(
struct dvb_frontend *fe,
const u8 buf[],
int len)
278 return si21_writereg(state, buf[0], buf[1]);
293 .addr = state->
config->demod_address,
303 dprintk(
"%s: readreg error (reg == 0x%02x, ret == %i)\n",
319 .addr = state->
config->demod_address,
329 dprintk(
"%s: readreg error (ret == %i)\n", __func__, ret);
331 return ret == 2 ? 0 : -1;
334 static int si21xx_wait_diseqc_idle(
struct si21xx_state *state,
int timeout)
341 if (jiffies - start > timeout) {
342 dprintk(
"%s: timeout!!\n", __func__);
354 u32 sym_rate, data_rate;
356 u8 sym_rate_bytes[3];
358 dprintk(
"%s : srate = %i\n", __func__ , srate);
360 if ((srate < 1000000) || (srate > 45000000))
366 for (i = 0; i < 4; ++
i) {
368 sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
372 for (i = 0; i < 3; ++
i)
373 sym_rate_bytes[i] = (
u8)((sym_rate >> (i * 8)) & 0xff);
380 static int si21xx_send_diseqc_msg(
struct dvb_frontend *fe,
394 status |= si21_readregs(state,
LNB_CTRL_REG_1, &lnb_status, 0x01);
399 LNB_CTRL_1 = (lnb_status & 0x70);
404 status |= si21_writeregs(state,
LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
409 static int si21xx_send_diseqc_burst(
struct dvb_frontend *fe,
417 if (si21xx_wait_diseqc_idle(state, 100) < 0)
420 val = (0x80 | si21_readreg(state, 0xc1));
422 burst ==
SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
425 if (si21xx_wait_diseqc_idle(state, 100) < 0)
489 for (i = 0; ; i += 2) {
490 reg1 = serit_sp1511lhb_inittab[
i];
491 val = serit_sp1511lhb_inittab[i+1];
492 if (reg1 == 0xff && val == 0xff)
494 si21_writeregs(state, reg1, &val, 1);
530 dprintk(
" %s : TS Set Error\n", __func__);
548 for (i = 0; i < 7; ++
i)
549 reg_read |= ((regs_read[0] >> i) & 0x01) << (6 -
i);
551 lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
553 dprintk(
"%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
568 if ((lock & 0x7b) == 0x7b)
574 static int si21_read_signal_strength(
struct dvb_frontend *fe,
u16 *strength)
581 u16 signal = (3 * si21_readreg(state, 0x27) *
582 si21_readreg(state, 0x28));
584 dprintk(
"%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
585 si21_readreg(state, 0x27),
586 si21_readreg(state, 0x28), (
int) signal);
603 *ber = (si21_readreg(state, 0x1d) << 8) |
604 si21_readreg(state, 0x1e);
613 s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
614 si21_readreg(state, 0x25));
615 xsnr = 3 * (xsnr - 0xa100);
616 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
632 *ucblocks = (si21_readreg(state, 0x1d) << 8) |
633 si21_readreg(state, 0x1e);
640 static int si21xx_setacquire(
struct dvb_frontend *fe,
int symbrate,
646 0x0, 0x01, 0x02, 0x04, 0x00,
647 0x8, 0x10, 0x20, 0x00, 0x3f
658 coderate_ptr = coderates[crate];
660 si21xx_set_symbolrate(fe, symbrate);
663 status |= si21_writeregs(state,
665 &coderate_ptr, 0x01);
677 status |= si21_writeregs(state,
681 status |= si21_writeregs(state,
684 status |= si21_writeregs(state,
687 status |= si21_writeregs(state,
702 unsigned char coarse_tune_freq;
706 bool inband_interferer_ind;
709 int icoarse_tune_freq;
711 unsigned int band_high;
712 unsigned int band_low;
722 196, 204, 205, 206, 207
732 unsigned char regs[4];
734 dprintk(
"%s : FE_SET_FRONTEND\n", __func__);
737 dprintk(
"%s: unsupported delivery system selected (%d)\n",
743 inband_interferer_div2[i] = inband_interferer_div4[i] =
false;
745 if_limit_high = -700000;
746 if_limit_low = -100000;
756 band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
757 + (data_rate * 135)) / 200;
759 band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
760 + (data_rate * 135)) / 200;
763 icoarse_tune_freq = 100000 *
764 (((rf_freq - lnb_lo) -
765 (if_limit_low + if_limit_high) / 2)
768 ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
771 x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
772 (afs[i] * 2500) + afs[
i] * 2500;
774 x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
777 if (((band_low < x1) && (x1 < band_high)) ||
778 ((band_low < x2) && (x2 < band_high)))
779 inband_interferer_div4[
i] =
true;
784 x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
785 (afs[i] * 5000) + afs[
i] * 5000;
787 x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
790 if (((band_low < x1) && (x1 < band_high)) ||
791 ((band_low < x2) && (x2 < band_high)))
792 inband_interferer_div2[
i] =
true;
795 inband_interferer_ind =
true;
797 if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
798 inband_interferer_ind =
false;
803 if (inband_interferer_ind) {
805 if (!inband_interferer_div2[i]) {
806 sample_rate = (
u8) afs[i];
812 if ((inband_interferer_div2[i] ||
813 !inband_interferer_div4[i])) {
814 sample_rate = (
u8) afs[i];
821 if (sample_rate > 207 || sample_rate < 192)
824 fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
825 ((sample_rate) * 1000));
827 coarse_tune_freq = (
u8)(icoarse_tune_freq / 100000);
829 regs[0] = sample_rate;
830 regs[1] = coarse_tune_freq;
831 regs[2] = fine_tune_freq & 0xFF;
832 regs[3] = fine_tune_freq >> 8 & 0xFF;
836 state->
fs = sample_rate;
869 .name =
"SL SI21XX DVB-S",
870 .frequency_min = 950000,
871 .frequency_max = 2150000,
872 .frequency_stepsize = 125,
873 .frequency_tolerance = 0,
874 .symbol_rate_min = 1000000,
875 .symbol_rate_max = 45000000,
876 .symbol_rate_tolerance = 500,
883 .release = si21xx_release,
885 .sleep = si21xx_sleep,
887 .read_status = si21_read_status,
888 .read_ber = si21_read_ber,
889 .read_signal_strength = si21_read_signal_strength,
890 .read_snr = si21_read_snr,
891 .read_ucblocks = si21_read_ucblocks,
892 .diseqc_send_master_cmd = si21xx_send_diseqc_msg,
893 .diseqc_send_burst = si21xx_send_diseqc_burst,
894 .set_tone = si21xx_set_tone,
895 .set_voltage = si21xx_set_voltage,
897 .set_frontend = si21xx_set_frontend,
923 id = si21_readreg(state, 0x00);
931 if (
id != 0x04 &&
id != 0x14)