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 <media/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
,
239 if (len
> sizeof(buf
) - 1)
243 memcpy(msg
.buf
+ 1, data
, len
);
245 ret
= i2c_transfer(state
->i2c
, &msg
, 1);
248 dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, ret == %i)\n",
249 __func__
, reg1
, data
[0], ret
);
251 return (ret
!= 1) ? -EREMOTEIO
: 0;
254 static int si21_writereg(struct si21xx_state
*state
, u8 reg
, u8 data
)
257 u8 buf
[] = { reg
, data
};
258 struct i2c_msg msg
= {
259 .addr
= state
->config
->demod_address
,
265 ret
= i2c_transfer(state
->i2c
, &msg
, 1);
268 dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, ret == %i)\n",
269 __func__
, reg
, data
, ret
);
271 return (ret
!= 1) ? -EREMOTEIO
: 0;
274 static int si21_write(struct dvb_frontend
*fe
, const u8 buf
[], int len
)
276 struct si21xx_state
*state
= fe
->demodulator_priv
;
281 return si21_writereg(state
, buf
[0], buf
[1]);
284 static u8
si21_readreg(struct si21xx_state
*state
, u8 reg
)
289 struct i2c_msg msg
[] = {
291 .addr
= state
->config
->demod_address
,
296 .addr
= state
->config
->demod_address
,
303 ret
= i2c_transfer(state
->i2c
, msg
, 2);
306 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
312 static int si21_readregs(struct si21xx_state
*state
, u8 reg1
, u8
*b
, u8 len
)
315 struct i2c_msg msg
[] = {
317 .addr
= state
->config
->demod_address
,
322 .addr
= state
->config
->demod_address
,
329 ret
= i2c_transfer(state
->i2c
, msg
, 2);
332 dprintk("%s: readreg error (ret == %i)\n", __func__
, ret
);
334 return ret
== 2 ? 0 : -1;
337 static int si21xx_wait_diseqc_idle(struct si21xx_state
*state
, int timeout
)
339 unsigned long start
= jiffies
;
341 dprintk("%s\n", __func__
);
343 while ((si21_readreg(state
, LNB_CTRL_REG_1
) & 0x8) == 8) {
344 if (jiffies
- start
> timeout
) {
345 dprintk("%s: timeout!!\n", __func__
);
354 static int si21xx_set_symbolrate(struct dvb_frontend
*fe
, u32 srate
)
356 struct si21xx_state
*state
= fe
->demodulator_priv
;
357 u32 sym_rate
, data_rate
;
359 u8 sym_rate_bytes
[3];
361 dprintk("%s : srate = %i\n", __func__
, srate
);
363 if ((srate
< 1000000) || (srate
> 45000000))
369 for (i
= 0; i
< 4; ++i
) {
371 sym_rate
= sym_rate
+ ((data_rate
% 100) * 0x800000) /
375 for (i
= 0; i
< 3; ++i
)
376 sym_rate_bytes
[i
] = (u8
)((sym_rate
>> (i
* 8)) & 0xff);
378 si21_writeregs(state
, SYM_RATE_REG_L
, sym_rate_bytes
, 0x03);
383 static int si21xx_send_diseqc_msg(struct dvb_frontend
*fe
,
384 struct dvb_diseqc_master_cmd
*m
)
386 struct si21xx_state
*state
= fe
->demodulator_priv
;
391 dprintk("%s\n", __func__
);
396 status
|= si21_readregs(state
, LNB_CTRL_STATUS_REG
, &lnb_status
, 0x01);
397 status
|= si21_readregs(state
, LNB_CTRL_REG_1
, &lnb_status
, 0x01);
400 status
|= si21_writeregs(state
, LNB_FIFO_REGS_0
, m
->msg
, m
->msg_len
);
402 LNB_CTRL_1
= (lnb_status
& 0x70);
403 LNB_CTRL_1
|= m
->msg_len
;
405 LNB_CTRL_1
|= 0x80; /* begin LNB signaling */
407 status
|= si21_writeregs(state
, LNB_CTRL_REG_1
, &LNB_CTRL_1
, 0x01);
412 static int si21xx_send_diseqc_burst(struct dvb_frontend
*fe
,
413 enum fe_sec_mini_cmd burst
)
415 struct si21xx_state
*state
= fe
->demodulator_priv
;
418 dprintk("%s\n", __func__
);
420 if (si21xx_wait_diseqc_idle(state
, 100) < 0)
423 val
= (0x80 | si21_readreg(state
, 0xc1));
424 if (si21_writereg(state
, LNB_CTRL_REG_1
,
425 burst
== SEC_MINI_A
? (val
& ~0x10) : (val
| 0x10)))
428 if (si21xx_wait_diseqc_idle(state
, 100) < 0)
431 if (si21_writereg(state
, LNB_CTRL_REG_1
, val
))
437 static int si21xx_set_tone(struct dvb_frontend
*fe
, enum fe_sec_tone_mode tone
)
439 struct si21xx_state
*state
= fe
->demodulator_priv
;
442 dprintk("%s\n", __func__
);
443 val
= (0x80 | si21_readreg(state
, LNB_CTRL_REG_1
));
447 return si21_writereg(state
, LNB_CTRL_REG_1
, val
| 0x20);
450 return si21_writereg(state
, LNB_CTRL_REG_1
, (val
& ~0x20));
457 static int si21xx_set_voltage(struct dvb_frontend
*fe
, enum fe_sec_voltage volt
)
459 struct si21xx_state
*state
= fe
->demodulator_priv
;
462 dprintk("%s: %s\n", __func__
,
463 volt
== SEC_VOLTAGE_13
? "SEC_VOLTAGE_13" :
464 volt
== SEC_VOLTAGE_18
? "SEC_VOLTAGE_18" : "??");
467 val
= (0x80 | si21_readreg(state
, LNB_CTRL_REG_1
));
471 return si21_writereg(state
, LNB_CTRL_REG_1
, val
| 0x40);
474 return si21_writereg(state
, LNB_CTRL_REG_1
, (val
& ~0x40));
481 static int si21xx_init(struct dvb_frontend
*fe
)
483 struct si21xx_state
*state
= fe
->demodulator_priv
;
490 dprintk("%s\n", __func__
);
492 for (i
= 0; ; i
+= 2) {
493 reg1
= serit_sp1511lhb_inittab
[i
];
494 val
= serit_sp1511lhb_inittab
[i
+1];
495 if (reg1
== 0xff && val
== 0xff)
497 si21_writeregs(state
, reg1
, &val
, 1);
500 /*DVB QPSK SYSTEM MODE REG*/
502 si21_writeregs(state
, SYSTEM_MODE_REG
, ®1
, 0x01);
504 /*transport stream config*/
507 sdata_form = LSB_FIRST;
508 clk_edge = FALLING_EDGE;
509 clk_mode = CLK_GAPPED_MODE;
510 strt_len = BYTE_WIDE;
511 sync_pol = ACTIVE_HIGH;
512 val_pol = ACTIVE_HIGH;
513 err_pol = ACTIVE_HIGH;
521 PARALLEL
+ (LSB_FIRST
<< 1)
522 + (FALLING_EDGE
<< 2) + (CLK_GAPPED_MODE
<< 3)
523 + (BYTE_WIDE
<< 4) + (ACTIVE_HIGH
<< 5)
524 + (ACTIVE_HIGH
<< 6) + (ACTIVE_HIGH
<< 7);
527 /* sclk_rate + (parity << 2)
528 + (data_delay << 3) + (clk_delay << 4)
529 + (pclk_smooth << 5);
531 status
|= si21_writeregs(state
, TS_CTRL_REG_1
, reg2
, 0x02);
533 dprintk(" %s : TS Set Error\n", __func__
);
539 static int si21_read_status(struct dvb_frontend
*fe
, enum fe_status
*status
)
541 struct si21xx_state
*state
= fe
->demodulator_priv
;
546 u8 signal
= si21_readreg(state
, ANALOG_AGC_POWER_LEVEL_REG
);
548 si21_readregs(state
, LOCK_STATUS_REG_1
, regs_read
, 0x02);
551 for (i
= 0; i
< 7; ++i
)
552 reg_read
|= ((regs_read
[0] >> i
) & 0x01) << (6 - i
);
554 lock
= ((reg_read
& 0x7f) | (regs_read
[1] & 0x80));
556 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__
, lock
);
560 *status
|= FE_HAS_SIGNAL
;
563 *status
|= FE_HAS_CARRIER
;
566 *status
|= FE_HAS_VITERBI
;
569 *status
|= FE_HAS_SYNC
;
571 if ((lock
& 0x7b) == 0x7b)
572 *status
|= FE_HAS_LOCK
;
577 static int si21_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
579 struct si21xx_state
*state
= fe
->demodulator_priv
;
581 /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
582 (u8*)agclevel, 0x01);*/
584 u16 signal
= (3 * si21_readreg(state
, 0x27) *
585 si21_readreg(state
, 0x28));
587 dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__
,
588 si21_readreg(state
, 0x27),
589 si21_readreg(state
, 0x28), (int) signal
);
597 static int si21_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
599 struct si21xx_state
*state
= fe
->demodulator_priv
;
601 dprintk("%s\n", __func__
);
603 if (state
->errmode
!= STATUS_BER
)
606 *ber
= (si21_readreg(state
, 0x1d) << 8) |
607 si21_readreg(state
, 0x1e);
612 static int si21_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
614 struct si21xx_state
*state
= fe
->demodulator_priv
;
616 s32 xsnr
= 0xffff - ((si21_readreg(state
, 0x24) << 8) |
617 si21_readreg(state
, 0x25));
618 xsnr
= 3 * (xsnr
- 0xa100);
619 *snr
= (xsnr
> 0xffff) ? 0xffff : (xsnr
< 0) ? 0 : xsnr
;
621 dprintk("%s\n", __func__
);
626 static int si21_read_ucblocks(struct dvb_frontend
*fe
, u32
*ucblocks
)
628 struct si21xx_state
*state
= fe
->demodulator_priv
;
630 dprintk("%s\n", __func__
);
632 if (state
->errmode
!= STATUS_UCBLOCKS
)
635 *ucblocks
= (si21_readreg(state
, 0x1d) << 8) |
636 si21_readreg(state
, 0x1e);
641 /* initiates a channel acquisition sequence
642 using the specified symbol rate and code rate */
643 static int si21xx_setacquire(struct dvb_frontend
*fe
, int symbrate
,
644 enum fe_code_rate crate
)
647 struct si21xx_state
*state
= fe
->demodulator_priv
;
649 0x0, 0x01, 0x02, 0x04, 0x00,
650 0x8, 0x10, 0x20, 0x00, 0x3f
658 dprintk("%s\n", __func__
);
661 coderate_ptr
= coderates
[crate
];
663 si21xx_set_symbolrate(fe
, symbrate
);
665 /* write code rates to use in the Viterbi search */
666 status
|= si21_writeregs(state
,
668 &coderate_ptr
, 0x01);
670 /* clear acq_start bit */
671 status
|= si21_readregs(state
, ACQ_CTRL_REG_2
, ®
, 0x01);
673 status
|= si21_writeregs(state
, ACQ_CTRL_REG_2
, ®
, 0x01);
675 /* use new Carrier Frequency Offset Estimator (QuickLock) */
680 status
|= si21_writeregs(state
,
681 TWO_DB_BNDWDTH_THRSHLD_REG
,
684 status
|= si21_writeregs(state
,
685 LSA_CTRL_REG_1
, ®
, 1);
687 status
|= si21_writeregs(state
,
688 BLIND_SCAN_CTRL_REG
, ®
, 1);
689 /* start automatic acq */
690 status
|= si21_writeregs(state
,
691 ACQ_CTRL_REG_2
, &start_acq
, 0x01);
696 static int si21xx_set_frontend(struct dvb_frontend
*fe
)
698 struct si21xx_state
*state
= fe
->demodulator_priv
;
699 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
701 /* freq Channel carrier frequency in KHz (i.e. 1550000 KHz)
702 datarate Channel symbol rate in Sps (i.e. 22500000 Sps)*/
705 unsigned char coarse_tune_freq
;
707 unsigned char sample_rate
= 0;
709 bool inband_interferer_ind
;
711 /* INTERMEDIATE VALUES */
712 int icoarse_tune_freq
; /* MHz */
713 int ifine_tune_freq
; /* MHz */
714 unsigned int band_high
;
715 unsigned int band_low
;
719 bool inband_interferer_div2
[ALLOWABLE_FS_COUNT
];
720 bool inband_interferer_div4
[ALLOWABLE_FS_COUNT
];
723 /* allowable sample rates for ADC in MHz */
724 int afs
[ALLOWABLE_FS_COUNT
] = { 200, 192, 193, 194, 195,
725 196, 204, 205, 206, 207
735 unsigned char regs
[4];
737 dprintk("%s : FE_SET_FRONTEND\n", __func__
);
739 if (c
->delivery_system
!= SYS_DVBS
) {
740 dprintk("%s: unsupported delivery system selected (%d)\n",
741 __func__
, c
->delivery_system
);
745 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
)
746 inband_interferer_div2
[i
] = inband_interferer_div4
[i
] = false;
748 if_limit_high
= -700000;
749 if_limit_low
= -100000;
754 rf_freq
= 10 * c
->frequency
;
755 data_rate
= c
->symbol_rate
/ 100;
759 band_low
= (rf_freq
- lnb_lo
) - ((lnb_uncertanity
* 200)
760 + (data_rate
* 135)) / 200;
762 band_high
= (rf_freq
- lnb_lo
) + ((lnb_uncertanity
* 200)
763 + (data_rate
* 135)) / 200;
766 icoarse_tune_freq
= 100000 *
767 (((rf_freq
- lnb_lo
) -
768 (if_limit_low
+ if_limit_high
) / 2)
771 ifine_tune_freq
= (rf_freq
- lnb_lo
) - icoarse_tune_freq
;
773 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
774 x1
= ((rf_freq
- lnb_lo
) / (afs
[i
] * 2500)) *
775 (afs
[i
] * 2500) + afs
[i
] * 2500;
777 x2
= ((rf_freq
- lnb_lo
) / (afs
[i
] * 2500)) *
780 if (((band_low
< x1
) && (x1
< band_high
)) ||
781 ((band_low
< x2
) && (x2
< band_high
)))
782 inband_interferer_div4
[i
] = true;
786 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
787 x1
= ((rf_freq
- lnb_lo
) / (afs
[i
] * 5000)) *
788 (afs
[i
] * 5000) + afs
[i
] * 5000;
790 x2
= ((rf_freq
- lnb_lo
) / (afs
[i
] * 5000)) *
793 if (((band_low
< x1
) && (x1
< band_high
)) ||
794 ((band_low
< x2
) && (x2
< band_high
)))
795 inband_interferer_div2
[i
] = true;
798 inband_interferer_ind
= true;
799 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
800 if (inband_interferer_div2
[i
] || inband_interferer_div4
[i
]) {
801 inband_interferer_ind
= false;
806 if (inband_interferer_ind
) {
807 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
808 if (!inband_interferer_div2
[i
]) {
809 sample_rate
= (u8
) afs
[i
];
814 for (i
= 0; i
< ALLOWABLE_FS_COUNT
; ++i
) {
815 if ((inband_interferer_div2
[i
] ||
816 !inband_interferer_div4
[i
])) {
817 sample_rate
= (u8
) afs
[i
];
824 if (sample_rate
> 207 || sample_rate
< 192)
827 fine_tune_freq
= ((0x4000 * (ifine_tune_freq
/ 10)) /
828 ((sample_rate
) * 1000));
830 coarse_tune_freq
= (u8
)(icoarse_tune_freq
/ 100000);
832 regs
[0] = sample_rate
;
833 regs
[1] = coarse_tune_freq
;
834 regs
[2] = fine_tune_freq
& 0xFF;
835 regs
[3] = fine_tune_freq
>> 8 & 0xFF;
837 status
|= si21_writeregs(state
, PLL_DIVISOR_REG
, ®s
[0], 0x04);
839 state
->fs
= sample_rate
;/*ADC MHz*/
840 si21xx_setacquire(fe
, c
->symbol_rate
, c
->fec_inner
);
845 static int si21xx_sleep(struct dvb_frontend
*fe
)
847 struct si21xx_state
*state
= fe
->demodulator_priv
;
850 dprintk("%s\n", __func__
);
852 si21_readregs(state
, SYSTEM_MODE_REG
, ®data
, 0x01);
854 si21_writeregs(state
, SYSTEM_MODE_REG
, ®data
, 0x01);
855 state
->initialised
= 0;
860 static void si21xx_release(struct dvb_frontend
*fe
)
862 struct si21xx_state
*state
= fe
->demodulator_priv
;
864 dprintk("%s\n", __func__
);
869 static const struct dvb_frontend_ops si21xx_ops
= {
870 .delsys
= { SYS_DVBS
},
872 .name
= "SL SI21XX DVB-S",
873 .frequency_min_hz
= 950 * MHz
,
874 .frequency_max_hz
= 2150 * MHz
,
875 .frequency_stepsize_hz
= 125 * kHz
,
876 .symbol_rate_min
= 1000000,
877 .symbol_rate_max
= 45000000,
878 .symbol_rate_tolerance
= 500, /* ppm */
879 .caps
= FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
880 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
|
885 .release
= si21xx_release
,
887 .sleep
= si21xx_sleep
,
889 .read_status
= si21_read_status
,
890 .read_ber
= si21_read_ber
,
891 .read_signal_strength
= si21_read_signal_strength
,
892 .read_snr
= si21_read_snr
,
893 .read_ucblocks
= si21_read_ucblocks
,
894 .diseqc_send_master_cmd
= si21xx_send_diseqc_msg
,
895 .diseqc_send_burst
= si21xx_send_diseqc_burst
,
896 .set_tone
= si21xx_set_tone
,
897 .set_voltage
= si21xx_set_voltage
,
899 .set_frontend
= si21xx_set_frontend
,
902 struct dvb_frontend
*si21xx_attach(const struct si21xx_config
*config
,
903 struct i2c_adapter
*i2c
)
905 struct si21xx_state
*state
= NULL
;
908 dprintk("%s\n", __func__
);
910 /* allocate memory for the internal state */
911 state
= kzalloc(sizeof(struct si21xx_state
), GFP_KERNEL
);
915 /* setup the state */
916 state
->config
= config
;
918 state
->initialised
= 0;
919 state
->errmode
= STATUS_BER
;
921 /* check if the demod is there */
922 id
= si21_readreg(state
, SYSTEM_MODE_REG
);
923 si21_writereg(state
, SYSTEM_MODE_REG
, id
| 0x40); /* standby off */
925 id
= si21_readreg(state
, 0x00);
927 /* register 0x00 contains:
933 if (id
!= 0x04 && id
!= 0x14)
936 /* create dvb_frontend */
937 memcpy(&state
->frontend
.ops
, &si21xx_ops
,
938 sizeof(struct dvb_frontend_ops
));
939 state
->frontend
.demodulator_priv
= state
;
940 return &state
->frontend
;
946 EXPORT_SYMBOL(si21xx_attach
);
948 module_param(debug
, int, 0644);
949 MODULE_PARM_DESC(debug
, "Turn on/off frontend debugging (default:off).");
951 MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
952 MODULE_AUTHOR("Igor M. Liplianin");
953 MODULE_LICENSE("GPL");