Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
0003 *
0004 * Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
0005 */
0006 #include <linux/init.h>
0007 #include <linux/kernel.h>
0008 #include <linux/module.h>
0009 #include <linux/string.h>
0010 #include <linux/slab.h>
0011 #include <linux/jiffies.h>
0012 #include <asm/div64.h>
0013 
0014 #include <media/dvb_frontend.h>
0015 #include "si21xx.h"
0016 
0017 #define REVISION_REG            0x00
0018 #define SYSTEM_MODE_REG         0x01
0019 #define TS_CTRL_REG_1           0x02
0020 #define TS_CTRL_REG_2           0x03
0021 #define PIN_CTRL_REG_1          0x04
0022 #define PIN_CTRL_REG_2          0x05
0023 #define LOCK_STATUS_REG_1       0x0f
0024 #define LOCK_STATUS_REG_2       0x10
0025 #define ACQ_STATUS_REG          0x11
0026 #define ACQ_CTRL_REG_1          0x13
0027 #define ACQ_CTRL_REG_2          0x14
0028 #define PLL_DIVISOR_REG         0x15
0029 #define COARSE_TUNE_REG         0x16
0030 #define FINE_TUNE_REG_L         0x17
0031 #define FINE_TUNE_REG_H         0x18
0032 
0033 #define ANALOG_AGC_POWER_LEVEL_REG  0x28
0034 #define CFO_ESTIMATOR_CTRL_REG_1    0x29
0035 #define CFO_ESTIMATOR_CTRL_REG_2    0x2a
0036 #define CFO_ESTIMATOR_CTRL_REG_3    0x2b
0037 
0038 #define SYM_RATE_ESTIMATE_REG_L     0x31
0039 #define SYM_RATE_ESTIMATE_REG_M     0x32
0040 #define SYM_RATE_ESTIMATE_REG_H     0x33
0041 
0042 #define CFO_ESTIMATOR_OFFSET_REG_L  0x36
0043 #define CFO_ESTIMATOR_OFFSET_REG_H  0x37
0044 #define CFO_ERROR_REG_L         0x38
0045 #define CFO_ERROR_REG_H         0x39
0046 #define SYM_RATE_ESTIMATOR_CTRL_REG 0x3a
0047 
0048 #define SYM_RATE_REG_L          0x3f
0049 #define SYM_RATE_REG_M          0x40
0050 #define SYM_RATE_REG_H          0x41
0051 #define SYM_RATE_ESTIMATOR_MAXIMUM_REG  0x42
0052 #define SYM_RATE_ESTIMATOR_MINIMUM_REG  0x43
0053 
0054 #define C_N_ESTIMATOR_CTRL_REG      0x7c
0055 #define C_N_ESTIMATOR_THRSHLD_REG   0x7d
0056 #define C_N_ESTIMATOR_LEVEL_REG_L   0x7e
0057 #define C_N_ESTIMATOR_LEVEL_REG_H   0x7f
0058 
0059 #define BLIND_SCAN_CTRL_REG     0x80
0060 
0061 #define LSA_CTRL_REG_1          0x8D
0062 #define SPCTRM_TILT_CORR_THRSHLD_REG    0x8f
0063 #define ONE_DB_BNDWDTH_THRSHLD_REG  0x90
0064 #define TWO_DB_BNDWDTH_THRSHLD_REG  0x91
0065 #define THREE_DB_BNDWDTH_THRSHLD_REG    0x92
0066 #define INBAND_POWER_THRSHLD_REG    0x93
0067 #define REF_NOISE_LVL_MRGN_THRSHLD_REG  0x94
0068 
0069 #define VIT_SRCH_CTRL_REG_1     0xa0
0070 #define VIT_SRCH_CTRL_REG_2     0xa1
0071 #define VIT_SRCH_CTRL_REG_3     0xa2
0072 #define VIT_SRCH_STATUS_REG     0xa3
0073 #define VITERBI_BER_COUNT_REG_L     0xab
0074 #define REED_SOLOMON_CTRL_REG       0xb0
0075 #define REED_SOLOMON_ERROR_COUNT_REG_L  0xb1
0076 #define PRBS_CTRL_REG           0xb5
0077 
0078 #define LNB_CTRL_REG_1          0xc0
0079 #define LNB_CTRL_REG_2          0xc1
0080 #define LNB_CTRL_REG_3          0xc2
0081 #define LNB_CTRL_REG_4          0xc3
0082 #define LNB_CTRL_STATUS_REG     0xc4
0083 #define LNB_FIFO_REGS_0         0xc5
0084 #define LNB_FIFO_REGS_1         0xc6
0085 #define LNB_FIFO_REGS_2         0xc7
0086 #define LNB_FIFO_REGS_3         0xc8
0087 #define LNB_FIFO_REGS_4         0xc9
0088 #define LNB_FIFO_REGS_5         0xca
0089 #define LNB_SUPPLY_CTRL_REG_1       0xcb
0090 #define LNB_SUPPLY_CTRL_REG_2       0xcc
0091 #define LNB_SUPPLY_CTRL_REG_3       0xcd
0092 #define LNB_SUPPLY_CTRL_REG_4       0xce
0093 #define LNB_SUPPLY_STATUS_REG       0xcf
0094 
0095 #define FAIL    -1
0096 #define PASS    0
0097 
0098 #define ALLOWABLE_FS_COUNT  10
0099 #define STATUS_BER      0
0100 #define STATUS_UCBLOCKS     1
0101 
0102 static int debug;
0103 #define dprintk(args...) \
0104     do { \
0105         if (debug) \
0106             printk(KERN_DEBUG "si21xx: " args); \
0107     } while (0)
0108 
0109 enum {
0110     ACTIVE_HIGH,
0111     ACTIVE_LOW
0112 };
0113 enum {
0114     BYTE_WIDE,
0115     BIT_WIDE
0116 };
0117 enum {
0118     CLK_GAPPED_MODE,
0119     CLK_CONTINUOUS_MODE
0120 };
0121 enum {
0122     RISING_EDGE,
0123     FALLING_EDGE
0124 };
0125 enum {
0126     MSB_FIRST,
0127     LSB_FIRST
0128 };
0129 enum {
0130     SERIAL,
0131     PARALLEL
0132 };
0133 
0134 struct si21xx_state {
0135     struct i2c_adapter *i2c;
0136     const struct si21xx_config *config;
0137     struct dvb_frontend frontend;
0138     u8 initialised:1;
0139     int errmode;
0140     int fs;         /*Sampling rate of the ADC in MHz*/
0141 };
0142 
0143 /*  register default initialization */
0144 static u8 serit_sp1511lhb_inittab[] = {
0145     0x01, 0x28, /* set i2c_inc_disable */
0146     0x20, 0x03,
0147     0x27, 0x20,
0148     0xe0, 0x45,
0149     0xe1, 0x08,
0150     0xfe, 0x01,
0151     0x01, 0x28,
0152     0x89, 0x09,
0153     0x04, 0x80,
0154     0x05, 0x01,
0155     0x06, 0x00,
0156     0x20, 0x03,
0157     0x24, 0x88,
0158     0x29, 0x09,
0159     0x2a, 0x0f,
0160     0x2c, 0x10,
0161     0x2d, 0x19,
0162     0x2e, 0x08,
0163     0x2f, 0x10,
0164     0x30, 0x19,
0165     0x34, 0x20,
0166     0x35, 0x03,
0167     0x45, 0x02,
0168     0x46, 0x45,
0169     0x47, 0xd0,
0170     0x48, 0x00,
0171     0x49, 0x40,
0172     0x4a, 0x03,
0173     0x4c, 0xfd,
0174     0x4f, 0x2e,
0175     0x50, 0x2e,
0176     0x51, 0x10,
0177     0x52, 0x10,
0178     0x56, 0x92,
0179     0x59, 0x00,
0180     0x5a, 0x2d,
0181     0x5b, 0x33,
0182     0x5c, 0x1f,
0183     0x5f, 0x76,
0184     0x62, 0xc0,
0185     0x63, 0xc0,
0186     0x64, 0xf3,
0187     0x65, 0xf3,
0188     0x79, 0x40,
0189     0x6a, 0x40,
0190     0x6b, 0x0a,
0191     0x6c, 0x80,
0192     0x6d, 0x27,
0193     0x71, 0x06,
0194     0x75, 0x60,
0195     0x78, 0x00,
0196     0x79, 0xb5,
0197     0x7c, 0x05,
0198     0x7d, 0x1a,
0199     0x87, 0x55,
0200     0x88, 0x72,
0201     0x8f, 0x08,
0202     0x90, 0xe0,
0203     0x94, 0x40,
0204     0xa0, 0x3f,
0205     0xa1, 0xc0,
0206     0xa4, 0xcc,
0207     0xa5, 0x66,
0208     0xa6, 0x66,
0209     0xa7, 0x7b,
0210     0xa8, 0x7b,
0211     0xa9, 0x7b,
0212     0xaa, 0x9a,
0213     0xed, 0x04,
0214     0xad, 0x00,
0215     0xae, 0x03,
0216     0xcc, 0xab,
0217     0x01, 0x08,
0218     0xff, 0xff
0219 };
0220 
0221 /*  low level read/writes */
0222 static int si21_writeregs(struct si21xx_state *state, u8 reg1,
0223                             u8 *data, int len)
0224 {
0225     int ret;
0226     u8 buf[60];/* = { reg1, data };*/
0227     struct i2c_msg msg = {
0228                 .addr = state->config->demod_address,
0229                 .flags = 0,
0230                 .buf = buf,
0231                 .len = len + 1
0232     };
0233 
0234     if (len > sizeof(buf) - 1)
0235         return -EINVAL;
0236 
0237     msg.buf[0] =  reg1;
0238     memcpy(msg.buf + 1, data, len);
0239 
0240     ret = i2c_transfer(state->i2c, &msg, 1);
0241 
0242     if (ret != 1)
0243         dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, ret == %i)\n",
0244             __func__, reg1, data[0], ret);
0245 
0246     return (ret != 1) ? -EREMOTEIO : 0;
0247 }
0248 
0249 static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
0250 {
0251     int ret;
0252     u8 buf[] = { reg, data };
0253     struct i2c_msg msg = {
0254                 .addr = state->config->demod_address,
0255                 .flags = 0,
0256                 .buf = buf,
0257                 .len = 2
0258     };
0259 
0260     ret = i2c_transfer(state->i2c, &msg, 1);
0261 
0262     if (ret != 1)
0263         dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, ret == %i)\n",
0264             __func__, reg, data, ret);
0265 
0266     return (ret != 1) ? -EREMOTEIO : 0;
0267 }
0268 
0269 static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len)
0270 {
0271     struct si21xx_state *state = fe->demodulator_priv;
0272 
0273     if (len != 2)
0274         return -EINVAL;
0275 
0276     return si21_writereg(state, buf[0], buf[1]);
0277 }
0278 
0279 static u8 si21_readreg(struct si21xx_state *state, u8 reg)
0280 {
0281     int ret;
0282     u8 b0[] = { reg };
0283     u8 b1[] = { 0 };
0284     struct i2c_msg msg[] = {
0285         {
0286             .addr = state->config->demod_address,
0287             .flags = 0,
0288             .buf = b0,
0289             .len = 1
0290         }, {
0291             .addr = state->config->demod_address,
0292             .flags = I2C_M_RD,
0293             .buf = b1,
0294             .len = 1
0295         }
0296     };
0297 
0298     ret = i2c_transfer(state->i2c, msg, 2);
0299 
0300     if (ret != 2)
0301         dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
0302             __func__, reg, ret);
0303 
0304     return b1[0];
0305 }
0306 
0307 static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
0308 {
0309     int ret;
0310     struct i2c_msg msg[] = {
0311         {
0312             .addr = state->config->demod_address,
0313             .flags = 0,
0314             .buf = &reg1,
0315             .len = 1
0316         }, {
0317             .addr = state->config->demod_address,
0318             .flags = I2C_M_RD,
0319             .buf = b,
0320             .len = len
0321         }
0322     };
0323 
0324     ret = i2c_transfer(state->i2c, msg, 2);
0325 
0326     if (ret != 2)
0327         dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
0328 
0329     return ret == 2 ? 0 : -1;
0330 }
0331 
0332 static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
0333 {
0334     unsigned long start = jiffies;
0335 
0336     dprintk("%s\n", __func__);
0337 
0338     while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
0339         if (time_is_before_jiffies(start + timeout)) {
0340             dprintk("%s: timeout!!\n", __func__);
0341             return -ETIMEDOUT;
0342         }
0343         msleep(10);
0344     }
0345 
0346     return 0;
0347 }
0348 
0349 static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
0350 {
0351     struct si21xx_state *state = fe->demodulator_priv;
0352     u32 sym_rate, data_rate;
0353     int i;
0354     u8 sym_rate_bytes[3];
0355 
0356     dprintk("%s : srate = %i\n", __func__ , srate);
0357 
0358     if ((srate < 1000000) || (srate > 45000000))
0359         return -EINVAL;
0360 
0361     data_rate = srate;
0362     sym_rate = 0;
0363 
0364     for (i = 0; i < 4; ++i) {
0365         sym_rate /= 100;
0366         sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
0367                                 state->fs;
0368         data_rate /= 100;
0369     }
0370     for (i = 0; i < 3; ++i)
0371         sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
0372 
0373     si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
0374 
0375     return 0;
0376 }
0377 
0378 static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
0379                     struct dvb_diseqc_master_cmd *m)
0380 {
0381     struct si21xx_state *state = fe->demodulator_priv;
0382     u8 lnb_status;
0383     u8 LNB_CTRL_1;
0384     int status;
0385 
0386     dprintk("%s\n", __func__);
0387 
0388     status = PASS;
0389     LNB_CTRL_1 = 0;
0390 
0391     status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
0392     status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
0393 
0394     /*fill the FIFO*/
0395     status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
0396 
0397     LNB_CTRL_1 = (lnb_status & 0x70);
0398     LNB_CTRL_1 |= m->msg_len;
0399 
0400     LNB_CTRL_1 |= 0x80; /* begin LNB signaling */
0401 
0402     status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
0403 
0404     return status;
0405 }
0406 
0407 static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
0408                     enum fe_sec_mini_cmd burst)
0409 {
0410     struct si21xx_state *state = fe->demodulator_priv;
0411     u8 val;
0412 
0413     dprintk("%s\n", __func__);
0414 
0415     if (si21xx_wait_diseqc_idle(state, 100) < 0)
0416         return -ETIMEDOUT;
0417 
0418     val = (0x80 | si21_readreg(state, 0xc1));
0419     if (si21_writereg(state, LNB_CTRL_REG_1,
0420             burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
0421         return -EREMOTEIO;
0422 
0423     if (si21xx_wait_diseqc_idle(state, 100) < 0)
0424         return -ETIMEDOUT;
0425 
0426     if (si21_writereg(state, LNB_CTRL_REG_1, val))
0427         return -EREMOTEIO;
0428 
0429     return 0;
0430 }
0431 /*  30.06.2008 */
0432 static int si21xx_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
0433 {
0434     struct si21xx_state *state = fe->demodulator_priv;
0435     u8 val;
0436 
0437     dprintk("%s\n", __func__);
0438     val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
0439 
0440     switch (tone) {
0441     case SEC_TONE_ON:
0442         return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
0443 
0444     case SEC_TONE_OFF:
0445         return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
0446 
0447     default:
0448         return -EINVAL;
0449     }
0450 }
0451 
0452 static int si21xx_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage volt)
0453 {
0454     struct si21xx_state *state = fe->demodulator_priv;
0455 
0456     u8 val;
0457     dprintk("%s: %s\n", __func__,
0458         volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
0459         volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
0460 
0461 
0462     val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
0463 
0464     switch (volt) {
0465     case SEC_VOLTAGE_18:
0466         return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
0467     case SEC_VOLTAGE_13:
0468         return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
0469     default:
0470         return -EINVAL;
0471     }
0472 }
0473 
0474 static int si21xx_init(struct dvb_frontend *fe)
0475 {
0476     struct si21xx_state *state = fe->demodulator_priv;
0477     int i;
0478     int status = 0;
0479     u8 reg1;
0480     u8 val;
0481     u8 reg2[2];
0482 
0483     dprintk("%s\n", __func__);
0484 
0485     for (i = 0; ; i += 2) {
0486         reg1 = serit_sp1511lhb_inittab[i];
0487         val = serit_sp1511lhb_inittab[i+1];
0488         if (reg1 == 0xff && val == 0xff)
0489             break;
0490         si21_writeregs(state, reg1, &val, 1);
0491     }
0492 
0493     /*DVB QPSK SYSTEM MODE REG*/
0494     reg1 = 0x08;
0495     si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
0496 
0497     /*transport stream config*/
0498     /*
0499     mode = PARALLEL;
0500     sdata_form = LSB_FIRST;
0501     clk_edge = FALLING_EDGE;
0502     clk_mode = CLK_GAPPED_MODE;
0503     strt_len = BYTE_WIDE;
0504     sync_pol = ACTIVE_HIGH;
0505     val_pol = ACTIVE_HIGH;
0506     err_pol = ACTIVE_HIGH;
0507     sclk_rate = 0x00;
0508     parity = 0x00 ;
0509     data_delay = 0x00;
0510     clk_delay = 0x00;
0511     pclk_smooth = 0x00;
0512     */
0513     reg2[0] =
0514         PARALLEL + (LSB_FIRST << 1)
0515         + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
0516         + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
0517         + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
0518 
0519     reg2[1] = 0;
0520     /*  sclk_rate + (parity << 2)
0521         + (data_delay << 3) + (clk_delay << 4)
0522         + (pclk_smooth << 5);
0523     */
0524     status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
0525     if (status != 0)
0526         dprintk(" %s : TS Set Error\n", __func__);
0527 
0528     return 0;
0529 
0530 }
0531 
0532 static int si21_read_status(struct dvb_frontend *fe, enum fe_status *status)
0533 {
0534     struct si21xx_state *state = fe->demodulator_priv;
0535     u8 regs_read[2];
0536     u8 reg_read;
0537     u8 i;
0538     u8 lock;
0539     u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
0540 
0541     si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
0542     reg_read = 0;
0543 
0544     for (i = 0; i < 7; ++i)
0545         reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
0546 
0547     lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
0548 
0549     dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
0550     *status = 0;
0551 
0552     if (signal > 10)
0553         *status |= FE_HAS_SIGNAL;
0554 
0555     if (lock & 0x2)
0556         *status |= FE_HAS_CARRIER;
0557 
0558     if (lock & 0x20)
0559         *status |= FE_HAS_VITERBI;
0560 
0561     if (lock & 0x40)
0562         *status |= FE_HAS_SYNC;
0563 
0564     if ((lock & 0x7b) == 0x7b)
0565         *status |= FE_HAS_LOCK;
0566 
0567     return 0;
0568 }
0569 
0570 static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
0571 {
0572     struct si21xx_state *state = fe->demodulator_priv;
0573 
0574     /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
0575                         (u8*)agclevel, 0x01);*/
0576 
0577     u16 signal = (3 * si21_readreg(state, 0x27) *
0578                     si21_readreg(state, 0x28));
0579 
0580     dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
0581         si21_readreg(state, 0x27),
0582         si21_readreg(state, 0x28), (int) signal);
0583 
0584     signal  <<= 4;
0585     *strength = signal;
0586 
0587     return 0;
0588 }
0589 
0590 static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
0591 {
0592     struct si21xx_state *state = fe->demodulator_priv;
0593 
0594     dprintk("%s\n", __func__);
0595 
0596     if (state->errmode != STATUS_BER)
0597         return 0;
0598 
0599     *ber = (si21_readreg(state, 0x1d) << 8) |
0600                 si21_readreg(state, 0x1e);
0601 
0602     return 0;
0603 }
0604 
0605 static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
0606 {
0607     struct si21xx_state *state = fe->demodulator_priv;
0608 
0609     s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
0610                     si21_readreg(state, 0x25));
0611     xsnr = 3 * (xsnr - 0xa100);
0612     *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
0613 
0614     dprintk("%s\n", __func__);
0615 
0616     return 0;
0617 }
0618 
0619 static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
0620 {
0621     struct si21xx_state *state = fe->demodulator_priv;
0622 
0623     dprintk("%s\n", __func__);
0624 
0625     if (state->errmode != STATUS_UCBLOCKS)
0626         *ucblocks = 0;
0627     else
0628         *ucblocks = (si21_readreg(state, 0x1d) << 8) |
0629                     si21_readreg(state, 0x1e);
0630 
0631     return 0;
0632 }
0633 
0634 /*  initiates a channel acquisition sequence
0635     using the specified symbol rate and code rate */
0636 static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
0637                  enum fe_code_rate crate)
0638 {
0639 
0640     struct si21xx_state *state = fe->demodulator_priv;
0641     u8 coderates[] = {
0642                 0x0, 0x01, 0x02, 0x04, 0x00,
0643                 0x8, 0x10, 0x20, 0x00, 0x3f
0644     };
0645 
0646     u8 coderate_ptr;
0647     int status;
0648     u8 start_acq = 0x80;
0649     u8 reg, regs[3];
0650 
0651     dprintk("%s\n", __func__);
0652 
0653     status = PASS;
0654     coderate_ptr = coderates[crate];
0655 
0656     si21xx_set_symbolrate(fe, symbrate);
0657 
0658     /* write code rates to use in the Viterbi search */
0659     status |= si21_writeregs(state,
0660                 VIT_SRCH_CTRL_REG_1,
0661                 &coderate_ptr, 0x01);
0662 
0663     /* clear acq_start bit */
0664     status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
0665     reg &= ~start_acq;
0666     status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
0667 
0668     /* use new Carrier Frequency Offset Estimator (QuickLock) */
0669     regs[0] = 0xCB;
0670     regs[1] = 0x40;
0671     regs[2] = 0xCB;
0672 
0673     status |= si21_writeregs(state,
0674                 TWO_DB_BNDWDTH_THRSHLD_REG,
0675                 &regs[0], 0x03);
0676     reg = 0x56;
0677     status |= si21_writeregs(state,
0678                 LSA_CTRL_REG_1, &reg, 1);
0679     reg = 0x05;
0680     status |= si21_writeregs(state,
0681                 BLIND_SCAN_CTRL_REG, &reg, 1);
0682     /* start automatic acq */
0683     status |= si21_writeregs(state,
0684                 ACQ_CTRL_REG_2, &start_acq, 0x01);
0685 
0686     return status;
0687 }
0688 
0689 static int si21xx_set_frontend(struct dvb_frontend *fe)
0690 {
0691     struct si21xx_state *state = fe->demodulator_priv;
0692     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0693 
0694     /* freq     Channel carrier frequency in KHz (i.e. 1550000 KHz)
0695      datarate   Channel symbol rate in Sps (i.e. 22500000 Sps)*/
0696 
0697     /* in MHz */
0698     unsigned char coarse_tune_freq;
0699     int fine_tune_freq;
0700     unsigned char sample_rate = 0;
0701     /* boolean */
0702     bool inband_interferer_ind;
0703 
0704     /* INTERMEDIATE VALUES */
0705     int icoarse_tune_freq; /* MHz */
0706     int ifine_tune_freq; /* MHz */
0707     unsigned int band_high;
0708     unsigned int band_low;
0709     unsigned int x1;
0710     unsigned int x2;
0711     int i;
0712     bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
0713     bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
0714     int status = 0;
0715 
0716     /* allowable sample rates for ADC in MHz */
0717     int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
0718                     196, 204, 205, 206, 207
0719     };
0720     /* in MHz */
0721     int if_limit_high;
0722     int if_limit_low;
0723     int lnb_lo;
0724     int lnb_uncertanity;
0725 
0726     int rf_freq;
0727     int data_rate;
0728     unsigned char regs[4];
0729 
0730     dprintk("%s : FE_SET_FRONTEND\n", __func__);
0731 
0732     if (c->delivery_system != SYS_DVBS) {
0733             dprintk("%s: unsupported delivery system selected (%d)\n",
0734                 __func__, c->delivery_system);
0735             return -EOPNOTSUPP;
0736     }
0737 
0738     for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
0739         inband_interferer_div2[i] = inband_interferer_div4[i] = false;
0740 
0741     if_limit_high = -700000;
0742     if_limit_low = -100000;
0743     /* in MHz */
0744     lnb_lo = 0;
0745     lnb_uncertanity = 0;
0746 
0747     rf_freq = 10 * c->frequency ;
0748     data_rate = c->symbol_rate / 100;
0749 
0750     band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
0751                     + (data_rate * 135)) / 200;
0752 
0753     band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
0754                     + (data_rate * 135)) / 200;
0755 
0756 
0757     icoarse_tune_freq = 100000 *
0758                 (((rf_freq - lnb_lo) -
0759                     (if_limit_low + if_limit_high) / 2)
0760                                 / 100000);
0761 
0762     ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
0763 
0764     for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
0765         x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
0766                     (afs[i] * 2500) + afs[i] * 2500;
0767 
0768         x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
0769                             (afs[i] * 2500);
0770 
0771         if (((band_low < x1) && (x1 < band_high)) ||
0772                     ((band_low < x2) && (x2 < band_high)))
0773                     inband_interferer_div4[i] = true;
0774 
0775     }
0776 
0777     for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
0778         x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
0779                     (afs[i] * 5000) + afs[i] * 5000;
0780 
0781         x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
0782                     (afs[i] * 5000);
0783 
0784         if (((band_low < x1) && (x1 < band_high)) ||
0785                     ((band_low < x2) && (x2 < band_high)))
0786                     inband_interferer_div2[i] = true;
0787     }
0788 
0789     inband_interferer_ind = true;
0790     for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
0791         if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
0792             inband_interferer_ind = false;
0793             break;
0794         }
0795     }
0796 
0797     if (inband_interferer_ind) {
0798         for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
0799             if (!inband_interferer_div2[i]) {
0800                 sample_rate = (u8) afs[i];
0801                 break;
0802             }
0803         }
0804     } else {
0805         for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
0806             if ((inband_interferer_div2[i] ||
0807                  !inband_interferer_div4[i])) {
0808                 sample_rate = (u8) afs[i];
0809                 break;
0810             }
0811         }
0812 
0813     }
0814 
0815     if (sample_rate > 207 || sample_rate < 192)
0816         sample_rate = 200;
0817 
0818     fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
0819                     ((sample_rate) * 1000));
0820 
0821     coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
0822 
0823     regs[0] = sample_rate;
0824     regs[1] = coarse_tune_freq;
0825     regs[2] = fine_tune_freq & 0xFF;
0826     regs[3] = fine_tune_freq >> 8 & 0xFF;
0827 
0828     status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
0829 
0830     state->fs = sample_rate;/*ADC MHz*/
0831     si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
0832 
0833     if (status)
0834         return -EREMOTEIO;
0835 
0836     return 0;
0837 }
0838 
0839 static int si21xx_sleep(struct dvb_frontend *fe)
0840 {
0841     struct si21xx_state *state = fe->demodulator_priv;
0842     u8 regdata;
0843 
0844     dprintk("%s\n", __func__);
0845 
0846     si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
0847     regdata |= 1 << 6;
0848     si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
0849     state->initialised = 0;
0850 
0851     return 0;
0852 }
0853 
0854 static void si21xx_release(struct dvb_frontend *fe)
0855 {
0856     struct si21xx_state *state = fe->demodulator_priv;
0857 
0858     dprintk("%s\n", __func__);
0859 
0860     kfree(state);
0861 }
0862 
0863 static const struct dvb_frontend_ops si21xx_ops = {
0864     .delsys = { SYS_DVBS },
0865     .info = {
0866         .name           = "SL SI21XX DVB-S",
0867         .frequency_min_hz   =  950 * MHz,
0868         .frequency_max_hz   = 2150 * MHz,
0869         .frequency_stepsize_hz  =  125 * kHz,
0870         .symbol_rate_min    = 1000000,
0871         .symbol_rate_max    = 45000000,
0872         .symbol_rate_tolerance  = 500,  /* ppm */
0873         .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
0874         FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
0875         FE_CAN_QPSK |
0876         FE_CAN_FEC_AUTO
0877     },
0878 
0879     .release = si21xx_release,
0880     .init = si21xx_init,
0881     .sleep = si21xx_sleep,
0882     .write = si21_write,
0883     .read_status = si21_read_status,
0884     .read_ber = si21_read_ber,
0885     .read_signal_strength = si21_read_signal_strength,
0886     .read_snr = si21_read_snr,
0887     .read_ucblocks = si21_read_ucblocks,
0888     .diseqc_send_master_cmd = si21xx_send_diseqc_msg,
0889     .diseqc_send_burst = si21xx_send_diseqc_burst,
0890     .set_tone = si21xx_set_tone,
0891     .set_voltage = si21xx_set_voltage,
0892 
0893     .set_frontend = si21xx_set_frontend,
0894 };
0895 
0896 struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
0897                         struct i2c_adapter *i2c)
0898 {
0899     struct si21xx_state *state = NULL;
0900     int id;
0901 
0902     dprintk("%s\n", __func__);
0903 
0904     /* allocate memory for the internal state */
0905     state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
0906     if (state == NULL)
0907         goto error;
0908 
0909     /* setup the state */
0910     state->config = config;
0911     state->i2c = i2c;
0912     state->initialised = 0;
0913     state->errmode = STATUS_BER;
0914 
0915     /* check if the demod is there */
0916     id = si21_readreg(state, SYSTEM_MODE_REG);
0917     si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
0918     msleep(200);
0919     id = si21_readreg(state, 0x00);
0920 
0921     /* register 0x00 contains:
0922         0x34 for SI2107
0923         0x24 for SI2108
0924         0x14 for SI2109
0925         0x04 for SI2110
0926     */
0927     if (id != 0x04 && id != 0x14)
0928         goto error;
0929 
0930     /* create dvb_frontend */
0931     memcpy(&state->frontend.ops, &si21xx_ops,
0932                     sizeof(struct dvb_frontend_ops));
0933     state->frontend.demodulator_priv = state;
0934     return &state->frontend;
0935 
0936 error:
0937     kfree(state);
0938     return NULL;
0939 }
0940 EXPORT_SYMBOL(si21xx_attach);
0941 
0942 module_param(debug, int, 0644);
0943 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
0944 
0945 MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
0946 MODULE_AUTHOR("Igor M. Liplianin");
0947 MODULE_LICENSE("GPL");