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
103 #define ALLOWABLE_FS_COUNT 10
105 #define STATUS_UCBLOCKS 1
108 #define dprintk(args...) \
111 printk(KERN_DEBUG "si21xx: " args); \
139 struct si21xx_state
{
140 struct i2c_adapter
*i2c
;
141 const struct si21xx_config
*config
;
142 struct dvb_frontend frontend
;
145 int fs
; /*Sampling rate of the ADC in MHz*/
148 /* register default initialization */
149 static u8 serit_sp1511lhb_inittab
[] = {
150 0x01, 0x28, /* set i2c_inc_disable */
226 /* low level read/writes */
227 static int si21_writeregs(struct si21xx_state
*state
, u8 reg1
,
231 u8 buf
[60];/* = { reg1, data };*/
232 struct i2c_msg msg
= {
233 .addr
= state
->config
->demod_address
,
240 memcpy(msg
.buf
+ 1, data
, len
);
242 ret
= i2c_transfer(state
->i2c
, &msg
, 1);
245 dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, "
246 "ret == %i)\n", __func__
, reg1
, data
[0], ret
);
248 return (ret
!= 1) ? -EREMOTEIO
: 0;
251 static int si21_writereg(struct si21xx_state
*state
, u8 reg
, u8 data
)
254 u8 buf
[] = { reg
, data
};
255 struct i2c_msg msg
= {
256 .addr
= state
->config
->demod_address
,
262 ret
= i2c_transfer(state
->i2c
, &msg
, 1);
265 dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, "
266 "ret == %i)\n", __func__
, reg
, data
, ret
);
268 return (ret
!= 1) ? -EREMOTEIO
: 0;
271 static int si21_write(struct dvb_frontend
*fe
, const u8 buf
[], int len
)
273 struct si21xx_state
*state
= fe
->demodulator_priv
;
278 return si21_writereg(state
, buf
[0], buf
[1]);
281 static u8
si21_readreg(struct si21xx_state
*state
, u8 reg
)
286 struct i2c_msg msg
[] = {
288 .addr
= state
->config
->demod_address
,
293 .addr
= state
->config
->demod_address
,
300 ret
= i2c_transfer(state
->i2c
, msg
, 2);
303 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
309 static int si21_readregs(struct si21xx_state
*state
, u8 reg1
, u8
*b
, u8 len
)
312 struct i2c_msg msg
[] = {
314 .addr
= state
->config
->demod_address
,
319 .addr
= state
->config
->demod_address
,
326 ret
= i2c_transfer(state
->i2c
, msg
, 2);
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
)
336 unsigned long start
= jiffies
;
338 dprintk("%s\n", __func__
);
340 while ((si21_readreg(state
, LNB_CTRL_REG_1
) & 0x8) == 8) {
341 if (jiffies
- start
> timeout
) {
342 dprintk("%s: timeout!!\n", __func__
);
351 static int si21xx_set_symbolrate(struct dvb_frontend
*fe
, u32 srate
)
353 struct si21xx_state
*state
= fe
->demodulator_priv
;
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);
375 si21_writeregs(state
, SYM_RATE_REG_L
, sym_rate_bytes
, 0x03);
380 static int si21xx_send_diseqc_msg(struct dvb_frontend
*fe
,
381 struct dvb_diseqc_master_cmd
*m
)
383 struct si21xx_state
*state
= fe
->demodulator_priv
;
388 dprintk("%s\n", __func__
);
393 status
|= si21_readregs(state
, LNB_CTRL_STATUS_REG
, &lnb_status
, 0x01);
394 status
|= si21_readregs(state
, LNB_CTRL_REG_1
, &lnb_status
, 0x01);
397 status
|= si21_writeregs(state
, LNB_FIFO_REGS_0
, m
->msg
, m
->msg_len
);
399 LNB_CTRL_1
= (lnb_status
& 0x70);
400 LNB_CTRL_1
|= m
->msg_len
;
402 LNB_CTRL_1
|= 0x80; /* begin LNB signaling */
404 status
|= si21_writeregs(state
, LNB_CTRL_REG_1
, &LNB_CTRL_1
, 0x01);
409 static int si21xx_send_diseqc_burst(struct dvb_frontend
*fe
,
410 fe_sec_mini_cmd_t burst
)
412 struct si21xx_state
*state
= fe
->demodulator_priv
;
415 dprintk("%s\n", __func__
);
417 if (si21xx_wait_diseqc_idle(state
, 100) < 0)
420 val
= (0x80 | si21_readreg(state
, 0xc1));
421 if (si21_writereg(state
, LNB_CTRL_REG_1
,
422 burst
== SEC_MINI_A
? (val
& ~0x10) : (val
| 0x10)))
425 if (si21xx_wait_diseqc_idle(state
, 100) < 0)
428 if (si21_writereg(state
, LNB_CTRL_REG_1
, val
))
434 static int si21xx_set_tone(struct dvb_frontend
*fe
, fe_sec_tone_mode_t tone
)
436 struct si21xx_state
*state
= fe
->demodulator_priv
;
439 dprintk("%s\n", __func__
);
440 val
= (0x80 | si21_readreg(state
, LNB_CTRL_REG_1
));
444 return si21_writereg(state
, LNB_CTRL_REG_1
, val
| 0x20);
447 return si21_writereg(state
, LNB_CTRL_REG_1
, (val
& ~0x20));
454 static int si21xx_set_voltage(struct dvb_frontend
*fe
, fe_sec_voltage_t volt
)
456 struct si21xx_state
*state
= fe
->demodulator_priv
;
459 dprintk("%s: %s\n", __func__
,
460 volt
== SEC_VOLTAGE_13
? "SEC_VOLTAGE_13" :
461 volt
== SEC_VOLTAGE_18
? "SEC_VOLTAGE_18" : "??");
464 val
= (0x80 | si21_readreg(state
, LNB_CTRL_REG_1
));
468 return si21_writereg(state
, LNB_CTRL_REG_1
, val
| 0x40);
471 return si21_writereg(state
, LNB_CTRL_REG_1
, (val
& ~0x40));
478 static int si21xx_init(struct dvb_frontend
*fe
)
480 struct si21xx_state
*state
= fe
->demodulator_priv
;
487 dprintk("%s\n", __func__
);
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);
497 /*DVB QPSK SYSTEM MODE REG*/
499 si21_writeregs(state
, SYSTEM_MODE_REG
, ®1
, 0x01);
501 /*transport stream config*/
504 sdata_form = LSB_FIRST;
505 clk_edge = FALLING_EDGE;
506 clk_mode = CLK_GAPPED_MODE;
507 strt_len = BYTE_WIDE;
508 sync_pol = ACTIVE_HIGH;
509 val_pol = ACTIVE_HIGH;
510 err_pol = ACTIVE_HIGH;
518 PARALLEL
+ (LSB_FIRST
<< 1)
519 + (FALLING_EDGE
<< 2) + (CLK_GAPPED_MODE
<< 3)
520 + (BYTE_WIDE
<< 4) + (ACTIVE_HIGH
<< 5)
521 + (ACTIVE_HIGH
<< 6) + (ACTIVE_HIGH
<< 7);
524 /* sclk_rate + (parity << 2)
525 + (data_delay << 3) + (clk_delay << 4)
526 + (pclk_smooth << 5);
528 status
|= si21_writeregs(state
, TS_CTRL_REG_1
, reg2
, 0x02);
530 dprintk(" %s : TS Set Error\n", __func__
);
536 static int si21_read_status(struct dvb_frontend
*fe
, fe_status_t
*status
)
538 struct si21xx_state
*state
= fe
->demodulator_priv
;
543 u8 signal
= si21_readreg(state
, ANALOG_AGC_POWER_LEVEL_REG
);
545 si21_readregs(state
, LOCK_STATUS_REG_1
, regs_read
, 0x02);
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
);
557 *status
|= FE_HAS_SIGNAL
;
560 *status
|= FE_HAS_CARRIER
;
563 *status
|= FE_HAS_VITERBI
;
566 *status
|= FE_HAS_SYNC
;
568 if ((lock
& 0x7b) == 0x7b)
569 *status
|= FE_HAS_LOCK
;
574 static int si21_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
576 struct si21xx_state
*state
= fe
->demodulator_priv
;
578 /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
579 (u8*)agclevel, 0x01);*/
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
);
594 static int si21_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
596 struct si21xx_state
*state
= fe
->demodulator_priv
;
598 dprintk("%s\n", __func__
);
600 if (state
->errmode
!= STATUS_BER
)
603 *ber
= (si21_readreg(state
, 0x1d) << 8) |
604 si21_readreg(state
, 0x1e);
609 static int si21_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
611 struct si21xx_state
*state
= fe
->demodulator_priv
;
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
;
618 dprintk("%s\n", __func__
);
623 static int si21_read_ucblocks(struct dvb_frontend
*fe
, u32
*ucblocks
)
625 struct si21xx_state
*state
= fe
->demodulator_priv
;
627 dprintk("%s\n", __func__
);
629 if (state
->errmode
!= STATUS_UCBLOCKS
)
632 *ucblocks
= (si21_readreg(state
, 0x1d) << 8) |
633 si21_readreg(state
, 0x1e);
638 /* initiates a channel acquisition sequence
639 using the specified symbol rate and code rate */
640 static int si21xx_setacquire(struct dvb_frontend
*fe
, int symbrate
,
641 fe_code_rate_t crate
)
644 struct si21xx_state
*state
= fe
->demodulator_priv
;
646 0x0, 0x01, 0x02, 0x04, 0x00,
647 0x8, 0x10, 0x20, 0x00, 0x3f
655 dprintk("%s\n", __func__
);
658 coderate_ptr
= coderates
[crate
];
660 si21xx_set_symbolrate(fe
, symbrate
);
662 /* write code rates to use in the Viterbi search */
663 status
|= si21_writeregs(state
,
665 &coderate_ptr
, 0x01);
667 /* clear acq_start bit */
668 status
|= si21_readregs(state
, ACQ_CTRL_REG_2
, ®
, 0x01);
670 status
|= si21_writeregs(state
, ACQ_CTRL_REG_2
, ®
, 0x01);
672 /* use new Carrier Frequency Offset Estimator (QuickLock) */
677 status
|= si21_writeregs(state
,
678 TWO_DB_BNDWDTH_THRSHLD_REG
,
681 status
|= si21_writeregs(state
,
682 LSA_CTRL_REG_1
, ®
, 1);
684 status
|= si21_writeregs(state
,
685 BLIND_SCAN_CTRL_REG
, ®
, 1);
686 /* start automatic acq */
687 status
|= si21_writeregs(state
,
688 ACQ_CTRL_REG_2
, &start_acq
, 0x01);
693 static int si21xx_set_property(struct dvb_frontend
*fe
, struct dtv_property
*p
)
695 dprintk("%s(..)\n", __func__
);
699 static int si21xx_get_property(struct dvb_frontend
*fe
, struct dtv_property
*p
)
701 dprintk("%s(..)\n", __func__
);
705 static int si21xx_set_frontend(struct dvb_frontend
*fe
,
706 struct dvb_frontend_parameters
*dfp
)
708 struct si21xx_state
*state
= fe
->demodulator_priv
;
709 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
711 /* freq Channel carrier frequency in KHz (i.e. 1550000 KHz)
712 datarate Channel symbol rate in Sps (i.e. 22500000 Sps)*/
715 unsigned char coarse_tune_freq
;
717 unsigned char sample_rate
= 0;
719 bool inband_interferer_ind
;
721 /* INTERMEDIATE VALUES */
722 int icoarse_tune_freq
; /* MHz */
723 int ifine_tune_freq
; /* MHz */
724 unsigned int band_high
;
725 unsigned int band_low
;
729 bool inband_interferer_div2
[ALLOWABLE_FS_COUNT
];
730 bool inband_interferer_div4
[ALLOWABLE_FS_COUNT
];
733 /* allowable sample rates for ADC in MHz */
734 int afs
[ALLOWABLE_FS_COUNT
] = { 200, 192, 193, 194, 195,
735 196, 204, 205, 206, 207
745 unsigned char regs
[4];
747 dprintk("%s : FE_SET_FRONTEND\n", __func__
);
749 if (c
->delivery_system
!= SYS_DVBS
) {
750 dprintk("%s: unsupported delivery system selected (%d)\n",
751 __func__
, c
->delivery_system
);
755 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
)
756 inband_interferer_div2
[i
] = inband_interferer_div4
[i
] = false;
758 if_limit_high
= -700000;
759 if_limit_low
= -100000;
764 rf_freq
= 10 * c
->frequency
;
765 data_rate
= c
->symbol_rate
/ 100;
769 band_low
= (rf_freq
- lnb_lo
) - ((lnb_uncertanity
* 200)
770 + (data_rate
* 135)) / 200;
772 band_high
= (rf_freq
- lnb_lo
) + ((lnb_uncertanity
* 200)
773 + (data_rate
* 135)) / 200;
776 icoarse_tune_freq
= 100000 *
777 (((rf_freq
- lnb_lo
) -
778 (if_limit_low
+ if_limit_high
) / 2)
781 ifine_tune_freq
= (rf_freq
- lnb_lo
) - icoarse_tune_freq
;
783 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
784 x1
= ((rf_freq
- lnb_lo
) / (afs
[i
] * 2500)) *
785 (afs
[i
] * 2500) + afs
[i
] * 2500;
787 x2
= ((rf_freq
- lnb_lo
) / (afs
[i
] * 2500)) *
790 if (((band_low
< x1
) && (x1
< band_high
)) ||
791 ((band_low
< x2
) && (x2
< band_high
)))
792 inband_interferer_div4
[i
] = true;
796 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
797 x1
= ((rf_freq
- lnb_lo
) / (afs
[i
] * 5000)) *
798 (afs
[i
] * 5000) + afs
[i
] * 5000;
800 x2
= ((rf_freq
- lnb_lo
) / (afs
[i
] * 5000)) *
803 if (((band_low
< x1
) && (x1
< band_high
)) ||
804 ((band_low
< x2
) && (x2
< band_high
)))
805 inband_interferer_div2
[i
] = true;
808 inband_interferer_ind
= true;
809 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
810 if (inband_interferer_div2
[i
] || inband_interferer_div4
[i
]) {
811 inband_interferer_ind
= false;
816 if (inband_interferer_ind
) {
817 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
818 if (!inband_interferer_div2
[i
]) {
819 sample_rate
= (u8
) afs
[i
];
824 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
825 if ((inband_interferer_div2
[i
] ||
826 !inband_interferer_div4
[i
])) {
827 sample_rate
= (u8
) afs
[i
];
834 if (sample_rate
> 207 || sample_rate
< 192)
837 fine_tune_freq
= ((0x4000 * (ifine_tune_freq
/ 10)) /
838 ((sample_rate
) * 1000));
840 coarse_tune_freq
= (u8
)(icoarse_tune_freq
/ 100000);
842 regs
[0] = sample_rate
;
843 regs
[1] = coarse_tune_freq
;
844 regs
[2] = fine_tune_freq
& 0xFF;
845 regs
[3] = fine_tune_freq
>> 8 & 0xFF;
847 status
|= si21_writeregs(state
, PLL_DIVISOR_REG
, ®s
[0], 0x04);
849 state
->fs
= sample_rate
;/*ADC MHz*/
850 si21xx_setacquire(fe
, c
->symbol_rate
, c
->fec_inner
);
855 static int si21xx_sleep(struct dvb_frontend
*fe
)
857 struct si21xx_state
*state
= fe
->demodulator_priv
;
860 dprintk("%s\n", __func__
);
862 si21_readregs(state
, SYSTEM_MODE_REG
, ®data
, 0x01);
864 si21_writeregs(state
, SYSTEM_MODE_REG
, ®data
, 0x01);
865 state
->initialised
= 0;
870 static void si21xx_release(struct dvb_frontend
*fe
)
872 struct si21xx_state
*state
= fe
->demodulator_priv
;
874 dprintk("%s\n", __func__
);
879 static struct dvb_frontend_ops si21xx_ops
= {
882 .name
= "SL SI21XX DVB-S",
884 .frequency_min
= 950000,
885 .frequency_max
= 2150000,
886 .frequency_stepsize
= 125, /* kHz for QPSK frontends */
887 .frequency_tolerance
= 0,
888 .symbol_rate_min
= 1000000,
889 .symbol_rate_max
= 45000000,
890 .symbol_rate_tolerance
= 500, /* ppm */
891 .caps
= FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
892 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
|
897 .release
= si21xx_release
,
899 .sleep
= si21xx_sleep
,
901 .read_status
= si21_read_status
,
902 .read_ber
= si21_read_ber
,
903 .read_signal_strength
= si21_read_signal_strength
,
904 .read_snr
= si21_read_snr
,
905 .read_ucblocks
= si21_read_ucblocks
,
906 .diseqc_send_master_cmd
= si21xx_send_diseqc_msg
,
907 .diseqc_send_burst
= si21xx_send_diseqc_burst
,
908 .set_tone
= si21xx_set_tone
,
909 .set_voltage
= si21xx_set_voltage
,
911 .set_property
= si21xx_set_property
,
912 .get_property
= si21xx_get_property
,
913 .set_frontend
= si21xx_set_frontend
,
916 struct dvb_frontend
*si21xx_attach(const struct si21xx_config
*config
,
917 struct i2c_adapter
*i2c
)
919 struct si21xx_state
*state
= NULL
;
922 dprintk("%s\n", __func__
);
924 /* allocate memory for the internal state */
925 state
= kzalloc(sizeof(struct si21xx_state
), GFP_KERNEL
);
929 /* setup the state */
930 state
->config
= config
;
932 state
->initialised
= 0;
933 state
->errmode
= STATUS_BER
;
935 /* check if the demod is there */
936 id
= si21_readreg(state
, SYSTEM_MODE_REG
);
937 si21_writereg(state
, SYSTEM_MODE_REG
, id
| 0x40); /* standby off */
939 id
= si21_readreg(state
, 0x00);
941 /* register 0x00 contains:
947 if (id
!= 0x04 && id
!= 0x14)
950 /* create dvb_frontend */
951 memcpy(&state
->frontend
.ops
, &si21xx_ops
,
952 sizeof(struct dvb_frontend_ops
));
953 state
->frontend
.demodulator_priv
= state
;
954 return &state
->frontend
;
960 EXPORT_SYMBOL(si21xx_attach
);
962 module_param(debug
, int, 0644);
963 MODULE_PARM_DESC(debug
, "Turn on/off frontend debugging (default:off).");
965 MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
966 MODULE_AUTHOR("Igor M. Liplianin");
967 MODULE_LICENSE("GPL");