[ARM] pxa: update defconfig for Verdex Pro
[linux-2.6/verdex.git] / drivers / media / dvb / frontends / si21xx.c
blob9552a22ccffb23b215897979fd51f45a2d8dc07a
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"
20 #include "si21xx.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
100 #define FALSE 0
101 #define TRUE 1
102 #define FAIL -1
103 #define PASS 0
105 #define ALLOWABLE_FS_COUNT 10
106 #define STATUS_BER 0
107 #define STATUS_UCBLOCKS 1
109 static int debug;
110 #define dprintk(args...) \
111 do { \
112 if (debug) \
113 printk(KERN_DEBUG "si21xx: " args); \
114 } while (0)
116 enum {
117 ACTIVE_HIGH,
118 ACTIVE_LOW
120 enum {
121 BYTE_WIDE,
122 BIT_WIDE
124 enum {
125 CLK_GAPPED_MODE,
126 CLK_CONTINUOUS_MODE
128 enum {
129 RISING_EDGE,
130 FALLING_EDGE
132 enum {
133 MSB_FIRST,
134 LSB_FIRST
136 enum {
137 SERIAL,
138 PARALLEL
141 struct si21xx_state {
142 struct i2c_adapter *i2c;
143 const struct si21xx_config *config;
144 struct dvb_frontend frontend;
145 u8 initialised:1;
146 int errmode;
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 */
153 0x20, 0x03,
154 0x27, 0x20,
155 0xe0, 0x45,
156 0xe1, 0x08,
157 0xfe, 0x01,
158 0x01, 0x28,
159 0x89, 0x09,
160 0x04, 0x80,
161 0x05, 0x01,
162 0x06, 0x00,
163 0x20, 0x03,
164 0x24, 0x88,
165 0x29, 0x09,
166 0x2a, 0x0f,
167 0x2c, 0x10,
168 0x2d, 0x19,
169 0x2e, 0x08,
170 0x2f, 0x10,
171 0x30, 0x19,
172 0x34, 0x20,
173 0x35, 0x03,
174 0x45, 0x02,
175 0x46, 0x45,
176 0x47, 0xd0,
177 0x48, 0x00,
178 0x49, 0x40,
179 0x4a, 0x03,
180 0x4c, 0xfd,
181 0x4f, 0x2e,
182 0x50, 0x2e,
183 0x51, 0x10,
184 0x52, 0x10,
185 0x56, 0x92,
186 0x59, 0x00,
187 0x5a, 0x2d,
188 0x5b, 0x33,
189 0x5c, 0x1f,
190 0x5f, 0x76,
191 0x62, 0xc0,
192 0x63, 0xc0,
193 0x64, 0xf3,
194 0x65, 0xf3,
195 0x79, 0x40,
196 0x6a, 0x40,
197 0x6b, 0x0a,
198 0x6c, 0x80,
199 0x6d, 0x27,
200 0x71, 0x06,
201 0x75, 0x60,
202 0x78, 0x00,
203 0x79, 0xb5,
204 0x7c, 0x05,
205 0x7d, 0x1a,
206 0x87, 0x55,
207 0x88, 0x72,
208 0x8f, 0x08,
209 0x90, 0xe0,
210 0x94, 0x40,
211 0xa0, 0x3f,
212 0xa1, 0xc0,
213 0xa4, 0xcc,
214 0xa5, 0x66,
215 0xa6, 0x66,
216 0xa7, 0x7b,
217 0xa8, 0x7b,
218 0xa9, 0x7b,
219 0xaa, 0x9a,
220 0xed, 0x04,
221 0xad, 0x00,
222 0xae, 0x03,
223 0xcc, 0xab,
224 0x01, 0x08,
225 0xff, 0xff
228 /* low level read/writes */
229 static int si21_writeregs(struct si21xx_state *state, u8 reg1,
230 u8 *data, int len)
232 int ret;
233 u8 buf[60];/* = { reg1, data };*/
234 struct i2c_msg msg = {
235 .addr = state->config->demod_address,
236 .flags = 0,
237 .buf = buf,
238 .len = len + 1
241 msg.buf[0] = reg1;
242 memcpy(msg.buf + 1, data, len);
244 ret = i2c_transfer(state->i2c, &msg, 1);
246 if (ret != 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)
255 int ret;
256 u8 buf[] = { reg, data };
257 struct i2c_msg msg = {
258 .addr = state->config->demod_address,
259 .flags = 0,
260 .buf = buf,
261 .len = 2
264 ret = i2c_transfer(state->i2c, &msg, 1);
266 if (ret != 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;
277 if (len != 2)
278 return -EINVAL;
280 return si21_writereg(state, buf[0], buf[1]);
283 static u8 si21_readreg(struct si21xx_state *state, u8 reg)
285 int ret;
286 u8 b0[] = { reg };
287 u8 b1[] = { 0 };
288 struct i2c_msg msg[] = {
290 .addr = state->config->demod_address,
291 .flags = 0,
292 .buf = b0,
293 .len = 1
294 }, {
295 .addr = state->config->demod_address,
296 .flags = I2C_M_RD,
297 .buf = b1,
298 .len = 1
302 ret = i2c_transfer(state->i2c, msg, 2);
304 if (ret != 2)
305 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
306 __func__, reg, ret);
308 return b1[0];
311 static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
313 int ret;
314 struct i2c_msg msg[] = {
316 .addr = state->config->demod_address,
317 .flags = 0,
318 .buf = &reg1,
319 .len = 1
320 }, {
321 .addr = state->config->demod_address,
322 .flags = I2C_M_RD,
323 .buf = b,
324 .len = len
328 ret = i2c_transfer(state->i2c, msg, 2);
330 if (ret != 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__);
345 return -ETIMEDOUT;
347 msleep(10);
350 return 0;
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;
357 int i;
358 u8 sym_rate_bytes[3];
360 dprintk("%s : srate = %i\n", __func__ , srate);
362 if ((srate < 1000000) || (srate > 45000000))
363 return -EINVAL;
365 data_rate = srate;
366 sym_rate = 0;
368 for (i = 0; i < 4; ++i) {
369 sym_rate /= 100;
370 sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
371 state->fs;
372 data_rate /= 100;
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);
379 return 0;
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;
386 u8 lnb_status;
387 u8 LNB_CTRL_1;
388 int status;
390 dprintk("%s\n", __func__);
392 status = PASS;
393 LNB_CTRL_1 = 0;
395 status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
396 status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
398 /*fill the FIFO*/
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);
408 return status;
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;
415 u8 val;
417 dprintk("%s\n", __func__);
419 if (si21xx_wait_diseqc_idle(state, 100) < 0)
420 return -ETIMEDOUT;
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)))
425 return -EREMOTEIO;
427 if (si21xx_wait_diseqc_idle(state, 100) < 0)
428 return -ETIMEDOUT;
430 if (si21_writereg(state, LNB_CTRL_REG_1, val))
431 return -EREMOTEIO;
433 return 0;
435 /* 30.06.2008 */
436 static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
438 struct si21xx_state *state = fe->demodulator_priv;
439 u8 val;
441 dprintk("%s\n", __func__);
442 val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
444 switch (tone) {
445 case SEC_TONE_ON:
446 return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
448 case SEC_TONE_OFF:
449 return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
451 default:
452 return -EINVAL;
456 static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
458 struct si21xx_state *state = fe->demodulator_priv;
460 u8 val;
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));
468 switch (volt) {
469 case SEC_VOLTAGE_18:
470 return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
471 break;
472 case SEC_VOLTAGE_13:
473 return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
474 break;
475 default:
476 return -EINVAL;
480 static int si21xx_init(struct dvb_frontend *fe)
482 struct si21xx_state *state = fe->demodulator_priv;
483 int i;
484 int status = 0;
485 u8 reg1;
486 u8 val;
487 u8 reg2[2];
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)
495 break;
496 si21_writeregs(state, reg1, &val, 1);
499 /*DVB QPSK SYSTEM MODE REG*/
500 reg1 = 0x08;
501 si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
503 /*transport stream config*/
505 mode = PARALLEL;
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;
513 sclk_rate = 0x00;
514 parity = 0x00 ;
515 data_delay = 0x00;
516 clk_delay = 0x00;
517 pclk_smooth = 0x00;
519 reg2[0] =
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);
525 reg2[1] = 0;
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);
531 if (status != 0)
532 dprintk(" %s : TS Set Error\n", __func__);
534 return 0;
538 static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status)
540 struct si21xx_state *state = fe->demodulator_priv;
541 u8 regs_read[2];
542 u8 reg_read;
543 u8 i;
544 u8 lock;
545 u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
547 si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
548 reg_read = 0;
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);
556 *status = 0;
558 if (signal > 10)
559 *status |= FE_HAS_SIGNAL;
561 if (lock & 0x2)
562 *status |= FE_HAS_CARRIER;
564 if (lock & 0x20)
565 *status |= FE_HAS_VITERBI;
567 if (lock & 0x40)
568 *status |= FE_HAS_SYNC;
570 if ((lock & 0x7b) == 0x7b)
571 *status |= FE_HAS_LOCK;
573 return 0;
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);
590 signal <<= 4;
591 *strength = signal;
593 return 0;
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)
603 return 0;
605 *ber = (si21_readreg(state, 0x1d) << 8) |
606 si21_readreg(state, 0x1e);
608 return 0;
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__);
622 return 0;
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)
632 *ucblocks = 0;
633 else
634 *ucblocks = (si21_readreg(state, 0x1d) << 8) |
635 si21_readreg(state, 0x1e);
637 return 0;
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;
647 u8 coderates[] = {
648 0x0, 0x01, 0x02, 0x04, 0x00,
649 0x8, 0x10, 0x20, 0x00, 0x3f
652 u8 coderate_ptr;
653 int status;
654 u8 start_acq = 0x80;
655 u8 reg, regs[3];
657 dprintk("%s\n", __func__);
659 status = PASS;
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,
666 VIT_SRCH_CTRL_REG_1,
667 &coderate_ptr, 0x01);
669 /* clear acq_start bit */
670 status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
671 reg &= ~start_acq;
672 status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
674 /* use new Carrier Frequency Offset Estimator (QuickLock) */
675 regs[0] = 0xCB;
676 regs[1] = 0x40;
677 regs[2] = 0xCB;
679 status |= si21_writeregs(state,
680 TWO_DB_BNDWDTH_THRSHLD_REG,
681 &regs[0], 0x03);
682 reg = 0x56;
683 status |= si21_writeregs(state,
684 LSA_CTRL_REG_1, &reg, 1);
685 reg = 0x05;
686 status |= si21_writeregs(state,
687 BLIND_SCAN_CTRL_REG, &reg, 1);
688 /* start automatic acq */
689 status |= si21_writeregs(state,
690 ACQ_CTRL_REG_2, &start_acq, 0x01);
692 return status;
695 static int si21xx_set_property(struct dvb_frontend *fe, struct dtv_property *p)
697 dprintk("%s(..)\n", __func__);
698 return 0;
701 static int si21xx_get_property(struct dvb_frontend *fe, struct dtv_property *p)
703 dprintk("%s(..)\n", __func__);
704 return 0;
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)*/
716 /* in MHz */
717 unsigned char coarse_tune_freq;
718 int fine_tune_freq;
719 unsigned char sample_rate = 0;
720 /* boolean */
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;
728 unsigned int x1;
729 unsigned int x2;
730 int i;
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
740 int status;
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
746 /* in MHz */
747 int if_limit_high;
748 int if_limit_low;
749 int lnb_lo;
750 int lnb_uncertanity;
752 int rf_freq;
753 int data_rate;
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);
761 return -EOPNOTSUPP;
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;
769 /* in MHz */
770 lnb_lo = 0;
771 lnb_uncertanity = 0;
773 rf_freq = 10 * c->frequency ;
774 data_rate = c->symbol_rate / 100;
776 status = PASS;
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)
788 / 100000);
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)) *
797 (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)) *
810 (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];
826 break;
829 } else {
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];
834 break;
840 if (sample_rate > 207 || sample_rate < 192)
841 sample_rate = 200;
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, &regs[0], 0x04);
855 state->fs = sample_rate;/*ADC MHz*/
856 si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
858 return 0;
861 static int si21xx_sleep(struct dvb_frontend *fe)
863 struct si21xx_state *state = fe->demodulator_priv;
864 u8 regdata;
866 dprintk("%s\n", __func__);
868 si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
869 regdata |= 1 << 6;
870 si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
871 state->initialised = 0;
873 return 0;
876 static void si21xx_release(struct dvb_frontend *fe)
878 struct si21xx_state *state = fe->demodulator_priv;
880 dprintk("%s\n", __func__);
882 kfree(state);
885 static struct dvb_frontend_ops si21xx_ops = {
887 .info = {
888 .name = "SL SI21XX DVB-S",
889 .type = FE_QPSK,
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 |
899 FE_CAN_QPSK |
900 FE_CAN_FEC_AUTO
903 .release = si21xx_release,
904 .init = si21xx_init,
905 .sleep = si21xx_sleep,
906 .write = si21_write,
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;
926 int id;
928 dprintk("%s\n", __func__);
930 /* allocate memory for the internal state */
931 state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
932 if (state == NULL)
933 goto error;
935 /* setup the state */
936 state->config = config;
937 state->i2c = i2c;
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 */
944 msleep(200);
945 id = si21_readreg(state, 0x00);
947 /* register 0x00 contains:
948 0x34 for SI2107
949 0x24 for SI2108
950 0x14 for SI2109
951 0x04 for SI2110
953 if (id != 0x04 && id != 0x14)
954 goto error;
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;
962 error:
963 kfree(state);
964 return NULL;
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");