1 /* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
3 * Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/string.h>
15 #include <linux/slab.h>
16 #include <linux/jiffies.h>
17 #include <asm/div64.h>
19 #include "dvb_frontend.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
105 #define ALLOWABLE_FS_COUNT 10
107 #define STATUS_UCBLOCKS 1
110 #define dprintk(args...) \
113 printk(KERN_DEBUG "si21xx: " args); \
141 struct si21xx_state
{
142 struct i2c_adapter
*i2c
;
143 const struct si21xx_config
*config
;
144 struct dvb_frontend frontend
;
147 int fs
; /*Sampling rate of the ADC in MHz*/
150 /* register default initialization */
151 static u8 serit_sp1511lhb_inittab
[] = {
152 0x01, 0x28, /* set i2c_inc_disable */
228 /* low level read/writes */
229 static int si21_writeregs(struct si21xx_state
*state
, u8 reg1
,
233 u8 buf
[60];/* = { reg1, data };*/
234 struct i2c_msg msg
= {
235 .addr
= state
->config
->demod_address
,
242 memcpy(msg
.buf
+ 1, data
, len
);
244 ret
= i2c_transfer(state
->i2c
, &msg
, 1);
247 dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, "
248 "ret == %i)\n", __func__
, reg1
, data
[0], ret
);
250 return (ret
!= 1) ? -EREMOTEIO
: 0;
253 static int si21_writereg(struct si21xx_state
*state
, u8 reg
, u8 data
)
256 u8 buf
[] = { reg
, data
};
257 struct i2c_msg msg
= {
258 .addr
= state
->config
->demod_address
,
264 ret
= i2c_transfer(state
->i2c
, &msg
, 1);
267 dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, "
268 "ret == %i)\n", __func__
, reg
, data
, ret
);
270 return (ret
!= 1) ? -EREMOTEIO
: 0;
273 static int si21_write(struct dvb_frontend
*fe
, u8
*buf
, int len
)
275 struct si21xx_state
*state
= fe
->demodulator_priv
;
280 return si21_writereg(state
, buf
[0], buf
[1]);
283 static u8
si21_readreg(struct si21xx_state
*state
, u8 reg
)
288 struct i2c_msg msg
[] = {
290 .addr
= state
->config
->demod_address
,
295 .addr
= state
->config
->demod_address
,
302 ret
= i2c_transfer(state
->i2c
, msg
, 2);
305 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
311 static int si21_readregs(struct si21xx_state
*state
, u8 reg1
, u8
*b
, u8 len
)
314 struct i2c_msg msg
[] = {
316 .addr
= state
->config
->demod_address
,
321 .addr
= state
->config
->demod_address
,
328 ret
= i2c_transfer(state
->i2c
, msg
, 2);
331 dprintk("%s: readreg error (ret == %i)\n", __func__
, ret
);
333 return ret
== 2 ? 0 : -1;
336 static int si21xx_wait_diseqc_idle(struct si21xx_state
*state
, int timeout
)
338 unsigned long start
= jiffies
;
340 dprintk("%s\n", __func__
);
342 while ((si21_readreg(state
, LNB_CTRL_REG_1
) & 0x8) == 8) {
343 if (jiffies
- start
> timeout
) {
344 dprintk("%s: timeout!!\n", __func__
);
353 static int si21xx_set_symbolrate(struct dvb_frontend
*fe
, u32 srate
)
355 struct si21xx_state
*state
= fe
->demodulator_priv
;
356 u32 sym_rate
, data_rate
;
358 u8 sym_rate_bytes
[3];
360 dprintk("%s : srate = %i\n", __func__
, srate
);
362 if ((srate
< 1000000) || (srate
> 45000000))
368 for (i
= 0; i
< 4; ++i
) {
370 sym_rate
= sym_rate
+ ((data_rate
% 100) * 0x800000) /
374 for (i
= 0; i
< 3; ++i
)
375 sym_rate_bytes
[i
] = (u8
)((sym_rate
>> (i
* 8)) & 0xff);
377 si21_writeregs(state
, SYM_RATE_REG_L
, sym_rate_bytes
, 0x03);
382 static int si21xx_send_diseqc_msg(struct dvb_frontend
*fe
,
383 struct dvb_diseqc_master_cmd
*m
)
385 struct si21xx_state
*state
= fe
->demodulator_priv
;
390 dprintk("%s\n", __func__
);
395 status
|= si21_readregs(state
, LNB_CTRL_STATUS_REG
, &lnb_status
, 0x01);
396 status
|= si21_readregs(state
, LNB_CTRL_REG_1
, &lnb_status
, 0x01);
399 status
|= si21_writeregs(state
, LNB_FIFO_REGS_0
, m
->msg
, m
->msg_len
);
401 LNB_CTRL_1
= (lnb_status
& 0x70);
402 LNB_CTRL_1
|= m
->msg_len
;
404 LNB_CTRL_1
|= 0x80; /* begin LNB signaling */
406 status
|= si21_writeregs(state
, LNB_CTRL_REG_1
, &LNB_CTRL_1
, 0x01);
411 static int si21xx_send_diseqc_burst(struct dvb_frontend
*fe
,
412 fe_sec_mini_cmd_t burst
)
414 struct si21xx_state
*state
= fe
->demodulator_priv
;
417 dprintk("%s\n", __func__
);
419 if (si21xx_wait_diseqc_idle(state
, 100) < 0)
422 val
= (0x80 | si21_readreg(state
, 0xc1));
423 if (si21_writereg(state
, LNB_CTRL_REG_1
,
424 burst
== SEC_MINI_A
? (val
& ~0x10) : (val
| 0x10)))
427 if (si21xx_wait_diseqc_idle(state
, 100) < 0)
430 if (si21_writereg(state
, LNB_CTRL_REG_1
, val
))
436 static int si21xx_set_tone(struct dvb_frontend
*fe
, fe_sec_tone_mode_t tone
)
438 struct si21xx_state
*state
= fe
->demodulator_priv
;
441 dprintk("%s\n", __func__
);
442 val
= (0x80 | si21_readreg(state
, LNB_CTRL_REG_1
));
446 return si21_writereg(state
, LNB_CTRL_REG_1
, val
| 0x20);
449 return si21_writereg(state
, LNB_CTRL_REG_1
, (val
& ~0x20));
456 static int si21xx_set_voltage(struct dvb_frontend
*fe
, fe_sec_voltage_t volt
)
458 struct si21xx_state
*state
= fe
->demodulator_priv
;
461 dprintk("%s: %s\n", __func__
,
462 volt
== SEC_VOLTAGE_13
? "SEC_VOLTAGE_13" :
463 volt
== SEC_VOLTAGE_18
? "SEC_VOLTAGE_18" : "??");
466 val
= (0x80 | si21_readreg(state
, LNB_CTRL_REG_1
));
470 return si21_writereg(state
, LNB_CTRL_REG_1
, val
| 0x40);
473 return si21_writereg(state
, LNB_CTRL_REG_1
, (val
& ~0x40));
480 static int si21xx_init(struct dvb_frontend
*fe
)
482 struct si21xx_state
*state
= fe
->demodulator_priv
;
489 dprintk("%s\n", __func__
);
491 for (i
= 0; ; i
+= 2) {
492 reg1
= serit_sp1511lhb_inittab
[i
];
493 val
= serit_sp1511lhb_inittab
[i
+1];
494 if (reg1
== 0xff && val
== 0xff)
496 si21_writeregs(state
, reg1
, &val
, 1);
499 /*DVB QPSK SYSTEM MODE REG*/
501 si21_writeregs(state
, SYSTEM_MODE_REG
, ®1
, 0x01);
503 /*transport stream config*/
506 sdata_form = LSB_FIRST;
507 clk_edge = FALLING_EDGE;
508 clk_mode = CLK_GAPPED_MODE;
509 strt_len = BYTE_WIDE;
510 sync_pol = ACTIVE_HIGH;
511 val_pol = ACTIVE_HIGH;
512 err_pol = ACTIVE_HIGH;
520 PARALLEL
+ (LSB_FIRST
<< 1)
521 + (FALLING_EDGE
<< 2) + (CLK_GAPPED_MODE
<< 3)
522 + (BYTE_WIDE
<< 4) + (ACTIVE_HIGH
<< 5)
523 + (ACTIVE_HIGH
<< 6) + (ACTIVE_HIGH
<< 7);
526 /* sclk_rate + (parity << 2)
527 + (data_delay << 3) + (clk_delay << 4)
528 + (pclk_smooth << 5);
530 status
|= si21_writeregs(state
, TS_CTRL_REG_1
, reg2
, 0x02);
532 dprintk(" %s : TS Set Error\n", __func__
);
538 static int si21_read_status(struct dvb_frontend
*fe
, fe_status_t
*status
)
540 struct si21xx_state
*state
= fe
->demodulator_priv
;
545 u8 signal
= si21_readreg(state
, ANALOG_AGC_POWER_LEVEL_REG
);
547 si21_readregs(state
, LOCK_STATUS_REG_1
, regs_read
, 0x02);
550 for (i
= 0; i
< 7; ++i
)
551 reg_read
|= ((regs_read
[0] >> i
) & 0x01) << (6 - i
);
553 lock
= ((reg_read
& 0x7f) | (regs_read
[1] & 0x80));
555 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__
, lock
);
559 *status
|= FE_HAS_SIGNAL
;
562 *status
|= FE_HAS_CARRIER
;
565 *status
|= FE_HAS_VITERBI
;
568 *status
|= FE_HAS_SYNC
;
570 if ((lock
& 0x7b) == 0x7b)
571 *status
|= FE_HAS_LOCK
;
576 static int si21_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
578 struct si21xx_state
*state
= fe
->demodulator_priv
;
580 /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
581 (u8*)agclevel, 0x01);*/
583 u16 signal
= (3 * si21_readreg(state
, 0x27) *
584 si21_readreg(state
, 0x28));
586 dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__
,
587 si21_readreg(state
, 0x27),
588 si21_readreg(state
, 0x28), (int) signal
);
596 static int si21_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
598 struct si21xx_state
*state
= fe
->demodulator_priv
;
600 dprintk("%s\n", __func__
);
602 if (state
->errmode
!= STATUS_BER
)
605 *ber
= (si21_readreg(state
, 0x1d) << 8) |
606 si21_readreg(state
, 0x1e);
611 static int si21_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
613 struct si21xx_state
*state
= fe
->demodulator_priv
;
615 s32 xsnr
= 0xffff - ((si21_readreg(state
, 0x24) << 8) |
616 si21_readreg(state
, 0x25));
617 xsnr
= 3 * (xsnr
- 0xa100);
618 *snr
= (xsnr
> 0xffff) ? 0xffff : (xsnr
< 0) ? 0 : xsnr
;
620 dprintk("%s\n", __func__
);
625 static int si21_read_ucblocks(struct dvb_frontend
*fe
, u32
*ucblocks
)
627 struct si21xx_state
*state
= fe
->demodulator_priv
;
629 dprintk("%s\n", __func__
);
631 if (state
->errmode
!= STATUS_UCBLOCKS
)
634 *ucblocks
= (si21_readreg(state
, 0x1d) << 8) |
635 si21_readreg(state
, 0x1e);
640 /* initiates a channel acquisition sequence
641 using the specified symbol rate and code rate */
642 static int si21xx_setacquire(struct dvb_frontend
*fe
, int symbrate
,
643 fe_code_rate_t crate
)
646 struct si21xx_state
*state
= fe
->demodulator_priv
;
648 0x0, 0x01, 0x02, 0x04, 0x00,
649 0x8, 0x10, 0x20, 0x00, 0x3f
657 dprintk("%s\n", __func__
);
660 coderate_ptr
= coderates
[crate
];
662 si21xx_set_symbolrate(fe
, symbrate
);
664 /* write code rates to use in the Viterbi search */
665 status
|= si21_writeregs(state
,
667 &coderate_ptr
, 0x01);
669 /* clear acq_start bit */
670 status
|= si21_readregs(state
, ACQ_CTRL_REG_2
, ®
, 0x01);
672 status
|= si21_writeregs(state
, ACQ_CTRL_REG_2
, ®
, 0x01);
674 /* use new Carrier Frequency Offset Estimator (QuickLock) */
679 status
|= si21_writeregs(state
,
680 TWO_DB_BNDWDTH_THRSHLD_REG
,
683 status
|= si21_writeregs(state
,
684 LSA_CTRL_REG_1
, ®
, 1);
686 status
|= si21_writeregs(state
,
687 BLIND_SCAN_CTRL_REG
, ®
, 1);
688 /* start automatic acq */
689 status
|= si21_writeregs(state
,
690 ACQ_CTRL_REG_2
, &start_acq
, 0x01);
695 static int si21xx_set_property(struct dvb_frontend
*fe
, struct dtv_property
*p
)
697 dprintk("%s(..)\n", __func__
);
701 static int si21xx_get_property(struct dvb_frontend
*fe
, struct dtv_property
*p
)
703 dprintk("%s(..)\n", __func__
);
707 static int si21xx_set_frontend(struct dvb_frontend
*fe
,
708 struct dvb_frontend_parameters
*dfp
)
710 struct si21xx_state
*state
= fe
->demodulator_priv
;
711 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
713 /* freq Channel carrier frequency in KHz (i.e. 1550000 KHz)
714 datarate Channel symbol rate in Sps (i.e. 22500000 Sps)*/
717 unsigned char coarse_tune_freq
;
719 unsigned char sample_rate
= 0;
721 unsigned int inband_interferer_ind
;
723 /* INTERMEDIATE VALUES */
724 int icoarse_tune_freq
; /* MHz */
725 int ifine_tune_freq
; /* MHz */
726 unsigned int band_high
;
727 unsigned int band_low
;
731 unsigned int inband_interferer_div2
[ALLOWABLE_FS_COUNT
] = {
732 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
,
733 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
735 unsigned int inband_interferer_div4
[ALLOWABLE_FS_COUNT
] = {
736 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
,
737 FALSE
, FALSE
, FALSE
, FALSE
, FALSE
742 /* allowable sample rates for ADC in MHz */
743 int afs
[ALLOWABLE_FS_COUNT
] = { 200, 192, 193, 194, 195,
744 196, 204, 205, 206, 207
754 unsigned char regs
[4];
756 dprintk("%s : FE_SET_FRONTEND\n", __func__
);
758 if (c
->delivery_system
!= SYS_DVBS
) {
759 dprintk("%s: unsupported delivery system selected (%d)\n",
760 __func__
, c
->delivery_system
);
764 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
)
765 inband_interferer_div2
[i
] = inband_interferer_div4
[i
] = FALSE
;
767 if_limit_high
= -700000;
768 if_limit_low
= -100000;
773 rf_freq
= 10 * c
->frequency
;
774 data_rate
= c
->symbol_rate
/ 100;
778 band_low
= (rf_freq
- lnb_lo
) - ((lnb_uncertanity
* 200)
779 + (data_rate
* 135)) / 200;
781 band_high
= (rf_freq
- lnb_lo
) + ((lnb_uncertanity
* 200)
782 + (data_rate
* 135)) / 200;
785 icoarse_tune_freq
= 100000 *
786 (((rf_freq
- lnb_lo
) -
787 (if_limit_low
+ if_limit_high
) / 2)
790 ifine_tune_freq
= (rf_freq
- lnb_lo
) - icoarse_tune_freq
;
792 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
793 x1
= ((rf_freq
- lnb_lo
) / (afs
[i
] * 2500)) *
794 (afs
[i
] * 2500) + afs
[i
] * 2500;
796 x2
= ((rf_freq
- lnb_lo
) / (afs
[i
] * 2500)) *
799 if (((band_low
< x1
) && (x1
< band_high
)) ||
800 ((band_low
< x2
) && (x2
< band_high
)))
801 inband_interferer_div4
[i
] = TRUE
;
805 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
806 x1
= ((rf_freq
- lnb_lo
) / (afs
[i
] * 5000)) *
807 (afs
[i
] * 5000) + afs
[i
] * 5000;
809 x2
= ((rf_freq
- lnb_lo
) / (afs
[i
] * 5000)) *
812 if (((band_low
< x1
) && (x1
< band_high
)) ||
813 ((band_low
< x2
) && (x2
< band_high
)))
814 inband_interferer_div2
[i
] = TRUE
;
817 inband_interferer_ind
= TRUE
;
818 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
)
819 inband_interferer_ind
&= inband_interferer_div2
[i
] |
820 inband_interferer_div4
[i
];
822 if (inband_interferer_ind
) {
823 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
824 if (inband_interferer_div2
[i
] == FALSE
) {
825 sample_rate
= (u8
) afs
[i
];
830 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
831 if ((inband_interferer_div2
[i
] |
832 inband_interferer_div4
[i
]) == FALSE
) {
833 sample_rate
= (u8
) afs
[i
];
840 if (sample_rate
> 207 || sample_rate
< 192)
843 fine_tune_freq
= ((0x4000 * (ifine_tune_freq
/ 10)) /
844 ((sample_rate
) * 1000));
846 coarse_tune_freq
= (u8
)(icoarse_tune_freq
/ 100000);
848 regs
[0] = sample_rate
;
849 regs
[1] = coarse_tune_freq
;
850 regs
[2] = fine_tune_freq
& 0xFF;
851 regs
[3] = fine_tune_freq
>> 8 & 0xFF;
853 status
|= si21_writeregs(state
, PLL_DIVISOR_REG
, ®s
[0], 0x04);
855 state
->fs
= sample_rate
;/*ADC MHz*/
856 si21xx_setacquire(fe
, c
->symbol_rate
, c
->fec_inner
);
861 static int si21xx_sleep(struct dvb_frontend
*fe
)
863 struct si21xx_state
*state
= fe
->demodulator_priv
;
866 dprintk("%s\n", __func__
);
868 si21_readregs(state
, SYSTEM_MODE_REG
, ®data
, 0x01);
870 si21_writeregs(state
, SYSTEM_MODE_REG
, ®data
, 0x01);
871 state
->initialised
= 0;
876 static void si21xx_release(struct dvb_frontend
*fe
)
878 struct si21xx_state
*state
= fe
->demodulator_priv
;
880 dprintk("%s\n", __func__
);
885 static struct dvb_frontend_ops si21xx_ops
= {
888 .name
= "SL SI21XX DVB-S",
890 .frequency_min
= 950000,
891 .frequency_max
= 2150000,
892 .frequency_stepsize
= 125, /* kHz for QPSK frontends */
893 .frequency_tolerance
= 0,
894 .symbol_rate_min
= 1000000,
895 .symbol_rate_max
= 45000000,
896 .symbol_rate_tolerance
= 500, /* ppm */
897 .caps
= FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
898 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
|
903 .release
= si21xx_release
,
905 .sleep
= si21xx_sleep
,
907 .read_status
= si21_read_status
,
908 .read_ber
= si21_read_ber
,
909 .read_signal_strength
= si21_read_signal_strength
,
910 .read_snr
= si21_read_snr
,
911 .read_ucblocks
= si21_read_ucblocks
,
912 .diseqc_send_master_cmd
= si21xx_send_diseqc_msg
,
913 .diseqc_send_burst
= si21xx_send_diseqc_burst
,
914 .set_tone
= si21xx_set_tone
,
915 .set_voltage
= si21xx_set_voltage
,
917 .set_property
= si21xx_set_property
,
918 .get_property
= si21xx_get_property
,
919 .set_frontend
= si21xx_set_frontend
,
922 struct dvb_frontend
*si21xx_attach(const struct si21xx_config
*config
,
923 struct i2c_adapter
*i2c
)
925 struct si21xx_state
*state
= NULL
;
928 dprintk("%s\n", __func__
);
930 /* allocate memory for the internal state */
931 state
= kzalloc(sizeof(struct si21xx_state
), GFP_KERNEL
);
935 /* setup the state */
936 state
->config
= config
;
938 state
->initialised
= 0;
939 state
->errmode
= STATUS_BER
;
941 /* check if the demod is there */
942 id
= si21_readreg(state
, SYSTEM_MODE_REG
);
943 si21_writereg(state
, SYSTEM_MODE_REG
, id
| 0x40); /* standby off */
945 id
= si21_readreg(state
, 0x00);
947 /* register 0x00 contains:
953 if (id
!= 0x04 && id
!= 0x14)
956 /* create dvb_frontend */
957 memcpy(&state
->frontend
.ops
, &si21xx_ops
,
958 sizeof(struct dvb_frontend_ops
));
959 state
->frontend
.demodulator_priv
= state
;
960 return &state
->frontend
;
966 EXPORT_SYMBOL(si21xx_attach
);
968 module_param(debug
, int, 0644);
969 MODULE_PARM_DESC(debug
, "Turn on/off frontend debugging (default:off).");
971 MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
972 MODULE_AUTHOR("Igor M. Liplianin");
973 MODULE_LICENSE("GPL");