0001
0002
0003
0004
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;
0141 };
0142
0143
0144 static u8 serit_sp1511lhb_inittab[] = {
0145 0x01, 0x28,
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
0222 static int si21_writeregs(struct si21xx_state *state, u8 reg1,
0223 u8 *data, int len)
0224 {
0225 int ret;
0226 u8 buf[60];
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 = ®1,
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
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;
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
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
0494 reg1 = 0x08;
0495 si21_writeregs(state, SYSTEM_MODE_REG, ®1, 0x01);
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
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
0521
0522
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
0575
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
0635
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
0659 status |= si21_writeregs(state,
0660 VIT_SRCH_CTRL_REG_1,
0661 &coderate_ptr, 0x01);
0662
0663
0664 status |= si21_readregs(state, ACQ_CTRL_REG_2, ®, 0x01);
0665 reg &= ~start_acq;
0666 status |= si21_writeregs(state, ACQ_CTRL_REG_2, ®, 0x01);
0667
0668
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 ®s[0], 0x03);
0676 reg = 0x56;
0677 status |= si21_writeregs(state,
0678 LSA_CTRL_REG_1, ®, 1);
0679 reg = 0x05;
0680 status |= si21_writeregs(state,
0681 BLIND_SCAN_CTRL_REG, ®, 1);
0682
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
0695
0696
0697
0698 unsigned char coarse_tune_freq;
0699 int fine_tune_freq;
0700 unsigned char sample_rate = 0;
0701
0702 bool inband_interferer_ind;
0703
0704
0705 int icoarse_tune_freq;
0706 int ifine_tune_freq;
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
0717 int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
0718 196, 204, 205, 206, 207
0719 };
0720
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
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, ®s[0], 0x04);
0829
0830 state->fs = sample_rate;
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, ®data, 0x01);
0847 regdata |= 1 << 6;
0848 si21_writeregs(state, SYSTEM_MODE_REG, ®data, 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,
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
0905 state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
0906 if (state == NULL)
0907 goto error;
0908
0909
0910 state->config = config;
0911 state->i2c = i2c;
0912 state->initialised = 0;
0913 state->errmode = STATUS_BER;
0914
0915
0916 id = si21_readreg(state, SYSTEM_MODE_REG);
0917 si21_writereg(state, SYSTEM_MODE_REG, id | 0x40);
0918 msleep(200);
0919 id = si21_readreg(state, 0x00);
0920
0921
0922
0923
0924
0925
0926
0927 if (id != 0x04 && id != 0x14)
0928 goto error;
0929
0930
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");