Linux 2.6.34-rc3
[pohmelfs.git] / drivers / media / dvb / frontends / si21xx.c
blobd21a327db62996bed8ed3808761ba6776fbb378d
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 FAIL -1
101 #define PASS 0
103 #define ALLOWABLE_FS_COUNT 10
104 #define STATUS_BER 0
105 #define STATUS_UCBLOCKS 1
107 static int debug;
108 #define dprintk(args...) \
109 do { \
110 if (debug) \
111 printk(KERN_DEBUG "si21xx: " args); \
112 } while (0)
114 enum {
115 ACTIVE_HIGH,
116 ACTIVE_LOW
118 enum {
119 BYTE_WIDE,
120 BIT_WIDE
122 enum {
123 CLK_GAPPED_MODE,
124 CLK_CONTINUOUS_MODE
126 enum {
127 RISING_EDGE,
128 FALLING_EDGE
130 enum {
131 MSB_FIRST,
132 LSB_FIRST
134 enum {
135 SERIAL,
136 PARALLEL
139 struct si21xx_state {
140 struct i2c_adapter *i2c;
141 const struct si21xx_config *config;
142 struct dvb_frontend frontend;
143 u8 initialised:1;
144 int errmode;
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 */
151 0x20, 0x03,
152 0x27, 0x20,
153 0xe0, 0x45,
154 0xe1, 0x08,
155 0xfe, 0x01,
156 0x01, 0x28,
157 0x89, 0x09,
158 0x04, 0x80,
159 0x05, 0x01,
160 0x06, 0x00,
161 0x20, 0x03,
162 0x24, 0x88,
163 0x29, 0x09,
164 0x2a, 0x0f,
165 0x2c, 0x10,
166 0x2d, 0x19,
167 0x2e, 0x08,
168 0x2f, 0x10,
169 0x30, 0x19,
170 0x34, 0x20,
171 0x35, 0x03,
172 0x45, 0x02,
173 0x46, 0x45,
174 0x47, 0xd0,
175 0x48, 0x00,
176 0x49, 0x40,
177 0x4a, 0x03,
178 0x4c, 0xfd,
179 0x4f, 0x2e,
180 0x50, 0x2e,
181 0x51, 0x10,
182 0x52, 0x10,
183 0x56, 0x92,
184 0x59, 0x00,
185 0x5a, 0x2d,
186 0x5b, 0x33,
187 0x5c, 0x1f,
188 0x5f, 0x76,
189 0x62, 0xc0,
190 0x63, 0xc0,
191 0x64, 0xf3,
192 0x65, 0xf3,
193 0x79, 0x40,
194 0x6a, 0x40,
195 0x6b, 0x0a,
196 0x6c, 0x80,
197 0x6d, 0x27,
198 0x71, 0x06,
199 0x75, 0x60,
200 0x78, 0x00,
201 0x79, 0xb5,
202 0x7c, 0x05,
203 0x7d, 0x1a,
204 0x87, 0x55,
205 0x88, 0x72,
206 0x8f, 0x08,
207 0x90, 0xe0,
208 0x94, 0x40,
209 0xa0, 0x3f,
210 0xa1, 0xc0,
211 0xa4, 0xcc,
212 0xa5, 0x66,
213 0xa6, 0x66,
214 0xa7, 0x7b,
215 0xa8, 0x7b,
216 0xa9, 0x7b,
217 0xaa, 0x9a,
218 0xed, 0x04,
219 0xad, 0x00,
220 0xae, 0x03,
221 0xcc, 0xab,
222 0x01, 0x08,
223 0xff, 0xff
226 /* low level read/writes */
227 static int si21_writeregs(struct si21xx_state *state, u8 reg1,
228 u8 *data, int len)
230 int ret;
231 u8 buf[60];/* = { reg1, data };*/
232 struct i2c_msg msg = {
233 .addr = state->config->demod_address,
234 .flags = 0,
235 .buf = buf,
236 .len = len + 1
239 msg.buf[0] = reg1;
240 memcpy(msg.buf + 1, data, len);
242 ret = i2c_transfer(state->i2c, &msg, 1);
244 if (ret != 1)
245 dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, "
246 "ret == %i)\n", __func__, reg1, data[0], ret);
248 return (ret != 1) ? -EREMOTEIO : 0;
251 static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
253 int ret;
254 u8 buf[] = { reg, data };
255 struct i2c_msg msg = {
256 .addr = state->config->demod_address,
257 .flags = 0,
258 .buf = buf,
259 .len = 2
262 ret = i2c_transfer(state->i2c, &msg, 1);
264 if (ret != 1)
265 dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, "
266 "ret == %i)\n", __func__, reg, data, ret);
268 return (ret != 1) ? -EREMOTEIO : 0;
271 static int si21_write(struct dvb_frontend *fe, u8 *buf, int len)
273 struct si21xx_state *state = fe->demodulator_priv;
275 if (len != 2)
276 return -EINVAL;
278 return si21_writereg(state, buf[0], buf[1]);
281 static u8 si21_readreg(struct si21xx_state *state, u8 reg)
283 int ret;
284 u8 b0[] = { reg };
285 u8 b1[] = { 0 };
286 struct i2c_msg msg[] = {
288 .addr = state->config->demod_address,
289 .flags = 0,
290 .buf = b0,
291 .len = 1
292 }, {
293 .addr = state->config->demod_address,
294 .flags = I2C_M_RD,
295 .buf = b1,
296 .len = 1
300 ret = i2c_transfer(state->i2c, msg, 2);
302 if (ret != 2)
303 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
304 __func__, reg, ret);
306 return b1[0];
309 static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
311 int ret;
312 struct i2c_msg msg[] = {
314 .addr = state->config->demod_address,
315 .flags = 0,
316 .buf = &reg1,
317 .len = 1
318 }, {
319 .addr = state->config->demod_address,
320 .flags = I2C_M_RD,
321 .buf = b,
322 .len = len
326 ret = i2c_transfer(state->i2c, msg, 2);
328 if (ret != 2)
329 dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
331 return ret == 2 ? 0 : -1;
334 static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
336 unsigned long start = jiffies;
338 dprintk("%s\n", __func__);
340 while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
341 if (jiffies - start > timeout) {
342 dprintk("%s: timeout!!\n", __func__);
343 return -ETIMEDOUT;
345 msleep(10);
348 return 0;
351 static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
353 struct si21xx_state *state = fe->demodulator_priv;
354 u32 sym_rate, data_rate;
355 int i;
356 u8 sym_rate_bytes[3];
358 dprintk("%s : srate = %i\n", __func__ , srate);
360 if ((srate < 1000000) || (srate > 45000000))
361 return -EINVAL;
363 data_rate = srate;
364 sym_rate = 0;
366 for (i = 0; i < 4; ++i) {
367 sym_rate /= 100;
368 sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
369 state->fs;
370 data_rate /= 100;
372 for (i = 0; i < 3; ++i)
373 sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
375 si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
377 return 0;
380 static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
381 struct dvb_diseqc_master_cmd *m)
383 struct si21xx_state *state = fe->demodulator_priv;
384 u8 lnb_status;
385 u8 LNB_CTRL_1;
386 int status;
388 dprintk("%s\n", __func__);
390 status = PASS;
391 LNB_CTRL_1 = 0;
393 status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
394 status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
396 /*fill the FIFO*/
397 status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
399 LNB_CTRL_1 = (lnb_status & 0x70);
400 LNB_CTRL_1 |= m->msg_len;
402 LNB_CTRL_1 |= 0x80; /* begin LNB signaling */
404 status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
406 return status;
409 static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
410 fe_sec_mini_cmd_t burst)
412 struct si21xx_state *state = fe->demodulator_priv;
413 u8 val;
415 dprintk("%s\n", __func__);
417 if (si21xx_wait_diseqc_idle(state, 100) < 0)
418 return -ETIMEDOUT;
420 val = (0x80 | si21_readreg(state, 0xc1));
421 if (si21_writereg(state, LNB_CTRL_REG_1,
422 burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
423 return -EREMOTEIO;
425 if (si21xx_wait_diseqc_idle(state, 100) < 0)
426 return -ETIMEDOUT;
428 if (si21_writereg(state, LNB_CTRL_REG_1, val))
429 return -EREMOTEIO;
431 return 0;
433 /* 30.06.2008 */
434 static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
436 struct si21xx_state *state = fe->demodulator_priv;
437 u8 val;
439 dprintk("%s\n", __func__);
440 val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
442 switch (tone) {
443 case SEC_TONE_ON:
444 return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
446 case SEC_TONE_OFF:
447 return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
449 default:
450 return -EINVAL;
454 static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
456 struct si21xx_state *state = fe->demodulator_priv;
458 u8 val;
459 dprintk("%s: %s\n", __func__,
460 volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
461 volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
464 val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
466 switch (volt) {
467 case SEC_VOLTAGE_18:
468 return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
469 break;
470 case SEC_VOLTAGE_13:
471 return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
472 break;
473 default:
474 return -EINVAL;
478 static int si21xx_init(struct dvb_frontend *fe)
480 struct si21xx_state *state = fe->demodulator_priv;
481 int i;
482 int status = 0;
483 u8 reg1;
484 u8 val;
485 u8 reg2[2];
487 dprintk("%s\n", __func__);
489 for (i = 0; ; i += 2) {
490 reg1 = serit_sp1511lhb_inittab[i];
491 val = serit_sp1511lhb_inittab[i+1];
492 if (reg1 == 0xff && val == 0xff)
493 break;
494 si21_writeregs(state, reg1, &val, 1);
497 /*DVB QPSK SYSTEM MODE REG*/
498 reg1 = 0x08;
499 si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
501 /*transport stream config*/
503 mode = PARALLEL;
504 sdata_form = LSB_FIRST;
505 clk_edge = FALLING_EDGE;
506 clk_mode = CLK_GAPPED_MODE;
507 strt_len = BYTE_WIDE;
508 sync_pol = ACTIVE_HIGH;
509 val_pol = ACTIVE_HIGH;
510 err_pol = ACTIVE_HIGH;
511 sclk_rate = 0x00;
512 parity = 0x00 ;
513 data_delay = 0x00;
514 clk_delay = 0x00;
515 pclk_smooth = 0x00;
517 reg2[0] =
518 PARALLEL + (LSB_FIRST << 1)
519 + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
520 + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
521 + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
523 reg2[1] = 0;
524 /* sclk_rate + (parity << 2)
525 + (data_delay << 3) + (clk_delay << 4)
526 + (pclk_smooth << 5);
528 status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
529 if (status != 0)
530 dprintk(" %s : TS Set Error\n", __func__);
532 return 0;
536 static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status)
538 struct si21xx_state *state = fe->demodulator_priv;
539 u8 regs_read[2];
540 u8 reg_read;
541 u8 i;
542 u8 lock;
543 u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
545 si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
546 reg_read = 0;
548 for (i = 0; i < 7; ++i)
549 reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
551 lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
553 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
554 *status = 0;
556 if (signal > 10)
557 *status |= FE_HAS_SIGNAL;
559 if (lock & 0x2)
560 *status |= FE_HAS_CARRIER;
562 if (lock & 0x20)
563 *status |= FE_HAS_VITERBI;
565 if (lock & 0x40)
566 *status |= FE_HAS_SYNC;
568 if ((lock & 0x7b) == 0x7b)
569 *status |= FE_HAS_LOCK;
571 return 0;
574 static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
576 struct si21xx_state *state = fe->demodulator_priv;
578 /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
579 (u8*)agclevel, 0x01);*/
581 u16 signal = (3 * si21_readreg(state, 0x27) *
582 si21_readreg(state, 0x28));
584 dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
585 si21_readreg(state, 0x27),
586 si21_readreg(state, 0x28), (int) signal);
588 signal <<= 4;
589 *strength = signal;
591 return 0;
594 static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
596 struct si21xx_state *state = fe->demodulator_priv;
598 dprintk("%s\n", __func__);
600 if (state->errmode != STATUS_BER)
601 return 0;
603 *ber = (si21_readreg(state, 0x1d) << 8) |
604 si21_readreg(state, 0x1e);
606 return 0;
609 static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
611 struct si21xx_state *state = fe->demodulator_priv;
613 s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
614 si21_readreg(state, 0x25));
615 xsnr = 3 * (xsnr - 0xa100);
616 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
618 dprintk("%s\n", __func__);
620 return 0;
623 static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
625 struct si21xx_state *state = fe->demodulator_priv;
627 dprintk("%s\n", __func__);
629 if (state->errmode != STATUS_UCBLOCKS)
630 *ucblocks = 0;
631 else
632 *ucblocks = (si21_readreg(state, 0x1d) << 8) |
633 si21_readreg(state, 0x1e);
635 return 0;
638 /* initiates a channel acquisition sequence
639 using the specified symbol rate and code rate */
640 static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
641 fe_code_rate_t crate)
644 struct si21xx_state *state = fe->demodulator_priv;
645 u8 coderates[] = {
646 0x0, 0x01, 0x02, 0x04, 0x00,
647 0x8, 0x10, 0x20, 0x00, 0x3f
650 u8 coderate_ptr;
651 int status;
652 u8 start_acq = 0x80;
653 u8 reg, regs[3];
655 dprintk("%s\n", __func__);
657 status = PASS;
658 coderate_ptr = coderates[crate];
660 si21xx_set_symbolrate(fe, symbrate);
662 /* write code rates to use in the Viterbi search */
663 status |= si21_writeregs(state,
664 VIT_SRCH_CTRL_REG_1,
665 &coderate_ptr, 0x01);
667 /* clear acq_start bit */
668 status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
669 reg &= ~start_acq;
670 status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
672 /* use new Carrier Frequency Offset Estimator (QuickLock) */
673 regs[0] = 0xCB;
674 regs[1] = 0x40;
675 regs[2] = 0xCB;
677 status |= si21_writeregs(state,
678 TWO_DB_BNDWDTH_THRSHLD_REG,
679 &regs[0], 0x03);
680 reg = 0x56;
681 status |= si21_writeregs(state,
682 LSA_CTRL_REG_1, &reg, 1);
683 reg = 0x05;
684 status |= si21_writeregs(state,
685 BLIND_SCAN_CTRL_REG, &reg, 1);
686 /* start automatic acq */
687 status |= si21_writeregs(state,
688 ACQ_CTRL_REG_2, &start_acq, 0x01);
690 return status;
693 static int si21xx_set_property(struct dvb_frontend *fe, struct dtv_property *p)
695 dprintk("%s(..)\n", __func__);
696 return 0;
699 static int si21xx_get_property(struct dvb_frontend *fe, struct dtv_property *p)
701 dprintk("%s(..)\n", __func__);
702 return 0;
705 static int si21xx_set_frontend(struct dvb_frontend *fe,
706 struct dvb_frontend_parameters *dfp)
708 struct si21xx_state *state = fe->demodulator_priv;
709 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
711 /* freq Channel carrier frequency in KHz (i.e. 1550000 KHz)
712 datarate Channel symbol rate in Sps (i.e. 22500000 Sps)*/
714 /* in MHz */
715 unsigned char coarse_tune_freq;
716 int fine_tune_freq;
717 unsigned char sample_rate = 0;
718 /* boolean */
719 bool inband_interferer_ind;
721 /* INTERMEDIATE VALUES */
722 int icoarse_tune_freq; /* MHz */
723 int ifine_tune_freq; /* MHz */
724 unsigned int band_high;
725 unsigned int band_low;
726 unsigned int x1;
727 unsigned int x2;
728 int i;
729 bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
730 bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
731 int status;
733 /* allowable sample rates for ADC in MHz */
734 int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
735 196, 204, 205, 206, 207
737 /* in MHz */
738 int if_limit_high;
739 int if_limit_low;
740 int lnb_lo;
741 int lnb_uncertanity;
743 int rf_freq;
744 int data_rate;
745 unsigned char regs[4];
747 dprintk("%s : FE_SET_FRONTEND\n", __func__);
749 if (c->delivery_system != SYS_DVBS) {
750 dprintk("%s: unsupported delivery system selected (%d)\n",
751 __func__, c->delivery_system);
752 return -EOPNOTSUPP;
755 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
756 inband_interferer_div2[i] = inband_interferer_div4[i] = false;
758 if_limit_high = -700000;
759 if_limit_low = -100000;
760 /* in MHz */
761 lnb_lo = 0;
762 lnb_uncertanity = 0;
764 rf_freq = 10 * c->frequency ;
765 data_rate = c->symbol_rate / 100;
767 status = PASS;
769 band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
770 + (data_rate * 135)) / 200;
772 band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
773 + (data_rate * 135)) / 200;
776 icoarse_tune_freq = 100000 *
777 (((rf_freq - lnb_lo) -
778 (if_limit_low + if_limit_high) / 2)
779 / 100000);
781 ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
783 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
784 x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
785 (afs[i] * 2500) + afs[i] * 2500;
787 x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
788 (afs[i] * 2500);
790 if (((band_low < x1) && (x1 < band_high)) ||
791 ((band_low < x2) && (x2 < band_high)))
792 inband_interferer_div4[i] = true;
796 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
797 x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
798 (afs[i] * 5000) + afs[i] * 5000;
800 x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
801 (afs[i] * 5000);
803 if (((band_low < x1) && (x1 < band_high)) ||
804 ((band_low < x2) && (x2 < band_high)))
805 inband_interferer_div2[i] = true;
808 inband_interferer_ind = true;
809 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
810 if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
811 inband_interferer_ind = false;
812 break;
816 if (inband_interferer_ind) {
817 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
818 if (!inband_interferer_div2[i]) {
819 sample_rate = (u8) afs[i];
820 break;
823 } else {
824 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
825 if ((inband_interferer_div2[i] ||
826 !inband_interferer_div4[i])) {
827 sample_rate = (u8) afs[i];
828 break;
834 if (sample_rate > 207 || sample_rate < 192)
835 sample_rate = 200;
837 fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
838 ((sample_rate) * 1000));
840 coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
842 regs[0] = sample_rate;
843 regs[1] = coarse_tune_freq;
844 regs[2] = fine_tune_freq & 0xFF;
845 regs[3] = fine_tune_freq >> 8 & 0xFF;
847 status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
849 state->fs = sample_rate;/*ADC MHz*/
850 si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
852 return 0;
855 static int si21xx_sleep(struct dvb_frontend *fe)
857 struct si21xx_state *state = fe->demodulator_priv;
858 u8 regdata;
860 dprintk("%s\n", __func__);
862 si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
863 regdata |= 1 << 6;
864 si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
865 state->initialised = 0;
867 return 0;
870 static void si21xx_release(struct dvb_frontend *fe)
872 struct si21xx_state *state = fe->demodulator_priv;
874 dprintk("%s\n", __func__);
876 kfree(state);
879 static struct dvb_frontend_ops si21xx_ops = {
881 .info = {
882 .name = "SL SI21XX DVB-S",
883 .type = FE_QPSK,
884 .frequency_min = 950000,
885 .frequency_max = 2150000,
886 .frequency_stepsize = 125, /* kHz for QPSK frontends */
887 .frequency_tolerance = 0,
888 .symbol_rate_min = 1000000,
889 .symbol_rate_max = 45000000,
890 .symbol_rate_tolerance = 500, /* ppm */
891 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
892 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
893 FE_CAN_QPSK |
894 FE_CAN_FEC_AUTO
897 .release = si21xx_release,
898 .init = si21xx_init,
899 .sleep = si21xx_sleep,
900 .write = si21_write,
901 .read_status = si21_read_status,
902 .read_ber = si21_read_ber,
903 .read_signal_strength = si21_read_signal_strength,
904 .read_snr = si21_read_snr,
905 .read_ucblocks = si21_read_ucblocks,
906 .diseqc_send_master_cmd = si21xx_send_diseqc_msg,
907 .diseqc_send_burst = si21xx_send_diseqc_burst,
908 .set_tone = si21xx_set_tone,
909 .set_voltage = si21xx_set_voltage,
911 .set_property = si21xx_set_property,
912 .get_property = si21xx_get_property,
913 .set_frontend = si21xx_set_frontend,
916 struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
917 struct i2c_adapter *i2c)
919 struct si21xx_state *state = NULL;
920 int id;
922 dprintk("%s\n", __func__);
924 /* allocate memory for the internal state */
925 state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
926 if (state == NULL)
927 goto error;
929 /* setup the state */
930 state->config = config;
931 state->i2c = i2c;
932 state->initialised = 0;
933 state->errmode = STATUS_BER;
935 /* check if the demod is there */
936 id = si21_readreg(state, SYSTEM_MODE_REG);
937 si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
938 msleep(200);
939 id = si21_readreg(state, 0x00);
941 /* register 0x00 contains:
942 0x34 for SI2107
943 0x24 for SI2108
944 0x14 for SI2109
945 0x04 for SI2110
947 if (id != 0x04 && id != 0x14)
948 goto error;
950 /* create dvb_frontend */
951 memcpy(&state->frontend.ops, &si21xx_ops,
952 sizeof(struct dvb_frontend_ops));
953 state->frontend.demodulator_priv = state;
954 return &state->frontend;
956 error:
957 kfree(state);
958 return NULL;
960 EXPORT_SYMBOL(si21xx_attach);
962 module_param(debug, int, 0644);
963 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
965 MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
966 MODULE_AUTHOR("Igor M. Liplianin");
967 MODULE_LICENSE("GPL");