blob: 9552a22ccffb23b215897979fd51f45a2d8dc07a [file] [log] [blame]
Igor M. Liplianin04ad28c2008-09-16 18:21:11 -03001/* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
2*
3* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
4*
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.
9*
10*/
Igor M. Liplianin04ad28c2008-09-16 18:21:11 -030011#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>
18
19#include "dvb_frontend.h"
20#include "si21xx.h"
21
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
37
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
42
43#define SYM_RATE_ESTIMATE_REG_L 0x31
44#define SYM_RATE_ESTIMATE_REG_M 0x32
45#define SYM_RATE_ESTIMATE_REG_H 0x33
46
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
52
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
58
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
63
64#define BLIND_SCAN_CTRL_REG 0x80
65
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
73
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
82
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
99
100#define FALSE 0
101#define TRUE 1
102#define FAIL -1
103#define PASS 0
104
105#define ALLOWABLE_FS_COUNT 10
106#define STATUS_BER 0
107#define STATUS_UCBLOCKS 1
108
109static int debug;
110#define dprintk(args...) \
111 do { \
112 if (debug) \
113 printk(KERN_DEBUG "si21xx: " args); \
114 } while (0)
115
116enum {
117 ACTIVE_HIGH,
118 ACTIVE_LOW
119};
120enum {
121 BYTE_WIDE,
122 BIT_WIDE
123};
124enum {
125 CLK_GAPPED_MODE,
126 CLK_CONTINUOUS_MODE
127};
128enum {
129 RISING_EDGE,
130 FALLING_EDGE
131};
132enum {
133 MSB_FIRST,
134 LSB_FIRST
135};
136enum {
137 SERIAL,
138 PARALLEL
139};
140
141struct 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*/
148};
149
150/* register default initialization */
151static 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
226};
227
228/* low level read/writes */
229static int si21_writeregs(struct si21xx_state *state, u8 reg1,
230 u8 *data, int len)
231{
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
239 };
240
241 msg.buf[0] = reg1;
242 memcpy(msg.buf + 1, data, len);
243
244 ret = i2c_transfer(state->i2c, &msg, 1);
245
246 if (ret != 1)
247 dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, "
248 "ret == %i)\n", __func__, reg1, data[0], ret);
249
250 return (ret != 1) ? -EREMOTEIO : 0;
251}
252
253static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
254{
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
262 };
263
264 ret = i2c_transfer(state->i2c, &msg, 1);
265
266 if (ret != 1)
267 dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, "
268 "ret == %i)\n", __func__, reg, data, ret);
269
270 return (ret != 1) ? -EREMOTEIO : 0;
271}
272
273static int si21_write(struct dvb_frontend *fe, u8 *buf, int len)
274{
275 struct si21xx_state *state = fe->demodulator_priv;
276
277 if (len != 2)
278 return -EINVAL;
279
280 return si21_writereg(state, buf[0], buf[1]);
281}
282
283static u8 si21_readreg(struct si21xx_state *state, u8 reg)
284{
285 int ret;
286 u8 b0[] = { reg };
287 u8 b1[] = { 0 };
288 struct i2c_msg msg[] = {
289 {
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
299 }
300 };
301
302 ret = i2c_transfer(state->i2c, msg, 2);
303
304 if (ret != 2)
305 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
306 __func__, reg, ret);
307
308 return b1[0];
309}
310
311static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
312{
313 int ret;
314 struct i2c_msg msg[] = {
315 {
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
325 }
326 };
327
328 ret = i2c_transfer(state->i2c, msg, 2);
329
330 if (ret != 2)
331 dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
332
333 return ret == 2 ? 0 : -1;
334}
335
336static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
337{
338 unsigned long start = jiffies;
339
340 dprintk("%s\n", __func__);
341
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;
346 }
347 msleep(10);
348 };
349
350 return 0;
351}
352
353static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
354{
355 struct si21xx_state *state = fe->demodulator_priv;
356 u32 sym_rate, data_rate;
357 int i;
358 u8 sym_rate_bytes[3];
359
360 dprintk("%s : srate = %i\n", __func__ , srate);
361
362 if ((srate < 1000000) || (srate > 45000000))
363 return -EINVAL;
364
365 data_rate = srate;
366 sym_rate = 0;
367
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;
373 }
374 for (i = 0; i < 3; ++i)
375 sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
376
377 si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
378
379 return 0;
380}
381
382static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
383 struct dvb_diseqc_master_cmd *m)
384{
385 struct si21xx_state *state = fe->demodulator_priv;
386 u8 lnb_status;
387 u8 LNB_CTRL_1;
388 int status;
389
390 dprintk("%s\n", __func__);
391
392 status = PASS;
393 LNB_CTRL_1 = 0;
394
395 status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
396 status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
397
398 /*fill the FIFO*/
399 status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
400
401 LNB_CTRL_1 = (lnb_status & 0x70);
402 LNB_CTRL_1 |= m->msg_len;
403
404 LNB_CTRL_1 |= 0x80; /* begin LNB signaling */
405
406 status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
407
408 return status;
409}
410
411static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
412 fe_sec_mini_cmd_t burst)
413{
414 struct si21xx_state *state = fe->demodulator_priv;
415 u8 val;
416
417 dprintk("%s\n", __func__);
418
419 if (si21xx_wait_diseqc_idle(state, 100) < 0)
420 return -ETIMEDOUT;
421
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;
426
427 if (si21xx_wait_diseqc_idle(state, 100) < 0)
428 return -ETIMEDOUT;
429
430 if (si21_writereg(state, LNB_CTRL_REG_1, val))
431 return -EREMOTEIO;
432
433 return 0;
434}
435/* 30.06.2008 */
436static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
437{
438 struct si21xx_state *state = fe->demodulator_priv;
439 u8 val;
440
441 dprintk("%s\n", __func__);
442 val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
443
444 switch (tone) {
445 case SEC_TONE_ON:
446 return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
447
448 case SEC_TONE_OFF:
449 return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
450
451 default:
452 return -EINVAL;
453 }
454}
455
456static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
457{
458 struct si21xx_state *state = fe->demodulator_priv;
459
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" : "??");
464
465
466 val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
467
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;
477 };
478}
479
480static int si21xx_init(struct dvb_frontend *fe)
481{
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];
488
489 dprintk("%s\n", __func__);
490
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);
497 }
498
499 /*DVB QPSK SYSTEM MODE REG*/
500 reg1 = 0x08;
501 si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
502
503 /*transport stream config*/
504 /*
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;
518 */
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);
524
525 reg2[1] = 0;
526 /* sclk_rate + (parity << 2)
527 + (data_delay << 3) + (clk_delay << 4)
528 + (pclk_smooth << 5);
529 */
530 status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
531 if (status != 0)
532 dprintk(" %s : TS Set Error\n", __func__);
533
534 return 0;
535
536}
537
538static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status)
539{
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);
546
547 si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
548 reg_read = 0;
549
550 for (i = 0; i < 7; ++i)
551 reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
552
553 lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
554
555 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
556 *status = 0;
557
558 if (signal > 10)
559 *status |= FE_HAS_SIGNAL;
560
561 if (lock & 0x2)
562 *status |= FE_HAS_CARRIER;
563
564 if (lock & 0x20)
565 *status |= FE_HAS_VITERBI;
566
567 if (lock & 0x40)
568 *status |= FE_HAS_SYNC;
569
570 if ((lock & 0x7b) == 0x7b)
571 *status |= FE_HAS_LOCK;
572
573 return 0;
574}
575
576static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
577{
578 struct si21xx_state *state = fe->demodulator_priv;
579
580 /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
581 (u8*)agclevel, 0x01);*/
582
583 u16 signal = (3 * si21_readreg(state, 0x27) *
584 si21_readreg(state, 0x28));
585
586 dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
587 si21_readreg(state, 0x27),
588 si21_readreg(state, 0x28), (int) signal);
589
590 signal <<= 4;
591 *strength = signal;
592
593 return 0;
594}
595
596static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
597{
598 struct si21xx_state *state = fe->demodulator_priv;
599
600 dprintk("%s\n", __func__);
601
602 if (state->errmode != STATUS_BER)
603 return 0;
604
605 *ber = (si21_readreg(state, 0x1d) << 8) |
606 si21_readreg(state, 0x1e);
607
608 return 0;
609}
610
611static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
612{
613 struct si21xx_state *state = fe->demodulator_priv;
614
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;
619
620 dprintk("%s\n", __func__);
621
622 return 0;
623}
624
625static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
626{
627 struct si21xx_state *state = fe->demodulator_priv;
628
629 dprintk("%s\n", __func__);
630
631 if (state->errmode != STATUS_UCBLOCKS)
632 *ucblocks = 0;
633 else
634 *ucblocks = (si21_readreg(state, 0x1d) << 8) |
635 si21_readreg(state, 0x1e);
636
637 return 0;
638}
639
640/* initiates a channel acquisition sequence
641 using the specified symbol rate and code rate */
642static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
643 fe_code_rate_t crate)
644{
645
646 struct si21xx_state *state = fe->demodulator_priv;
647 u8 coderates[] = {
648 0x0, 0x01, 0x02, 0x04, 0x00,
649 0x8, 0x10, 0x20, 0x00, 0x3f
650 };
651
652 u8 coderate_ptr;
653 int status;
654 u8 start_acq = 0x80;
655 u8 reg, regs[3];
656
657 dprintk("%s\n", __func__);
658
659 status = PASS;
660 coderate_ptr = coderates[crate];
661
662 si21xx_set_symbolrate(fe, symbrate);
663
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);
668
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);
673
674 /* use new Carrier Frequency Offset Estimator (QuickLock) */
675 regs[0] = 0xCB;
676 regs[1] = 0x40;
677 regs[2] = 0xCB;
678
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);
691
692 return status;
693}
694
695static int si21xx_set_property(struct dvb_frontend *fe, struct dtv_property *p)
696{
697 dprintk("%s(..)\n", __func__);
698 return 0;
699}
700
701static int si21xx_get_property(struct dvb_frontend *fe, struct dtv_property *p)
702{
703 dprintk("%s(..)\n", __func__);
704 return 0;
705}
706
707static int si21xx_set_frontend(struct dvb_frontend *fe,
708 struct dvb_frontend_parameters *dfp)
709{
710 struct si21xx_state *state = fe->demodulator_priv;
711 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
712
713 /* freq Channel carrier frequency in KHz (i.e. 1550000 KHz)
714 datarate Channel symbol rate in Sps (i.e. 22500000 Sps)*/
715
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;
722
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
734 };
735 unsigned int inband_interferer_div4[ALLOWABLE_FS_COUNT] = {
736 FALSE, FALSE, FALSE, FALSE, FALSE,
737 FALSE, FALSE, FALSE, FALSE, FALSE
738 };
739
740 int status;
741
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
745 };
746 /* in MHz */
747 int if_limit_high;
748 int if_limit_low;
749 int lnb_lo;
750 int lnb_uncertanity;
751
752 int rf_freq;
753 int data_rate;
754 unsigned char regs[4];
755
756 dprintk("%s : FE_SET_FRONTEND\n", __func__);
757
758 if (c->delivery_system != SYS_DVBS) {
759 dprintk("%s: unsupported delivery system selected (%d)\n",
760 __func__, c->delivery_system);
761 return -EOPNOTSUPP;
762 }
763
764 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
765 inband_interferer_div2[i] = inband_interferer_div4[i] = FALSE;
766
767 if_limit_high = -700000;
768 if_limit_low = -100000;
769 /* in MHz */
770 lnb_lo = 0;
771 lnb_uncertanity = 0;
772
773 rf_freq = 10 * c->frequency ;
774 data_rate = c->symbol_rate / 100;
775
776 status = PASS;
777
778 band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
779 + (data_rate * 135)) / 200;
780
781 band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
782 + (data_rate * 135)) / 200;
783
784
785 icoarse_tune_freq = 100000 *
786 (((rf_freq - lnb_lo) -
787 (if_limit_low + if_limit_high) / 2)
788 / 100000);
789
790 ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
791
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;
795
796 x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
797 (afs[i] * 2500);
798
799 if (((band_low < x1) && (x1 < band_high)) ||
800 ((band_low < x2) && (x2 < band_high)))
801 inband_interferer_div4[i] = TRUE;
802
803 }
804
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;
808
809 x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
810 (afs[i] * 5000);
811
812 if (((band_low < x1) && (x1 < band_high)) ||
813 ((band_low < x2) && (x2 < band_high)))
814 inband_interferer_div2[i] = TRUE;
815 }
816
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];
821
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;
827 }
828 }
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;
835 }
836 }
837
838 }
839
840 if (sample_rate > 207 || sample_rate < 192)
841 sample_rate = 200;
842
843 fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
844 ((sample_rate) * 1000));
845
846 coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
847
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;
852
853 status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
854
855 state->fs = sample_rate;/*ADC MHz*/
856 si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
857
858 return 0;
859}
860
861static int si21xx_sleep(struct dvb_frontend *fe)
862{
863 struct si21xx_state *state = fe->demodulator_priv;
864 u8 regdata;
865
866 dprintk("%s\n", __func__);
867
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;
872
873 return 0;
874}
875
876static void si21xx_release(struct dvb_frontend *fe)
877{
878 struct si21xx_state *state = fe->demodulator_priv;
879
880 dprintk("%s\n", __func__);
881
882 kfree(state);
883}
884
885static struct dvb_frontend_ops si21xx_ops = {
886
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
901 },
902
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,
916
917 .set_property = si21xx_set_property,
918 .get_property = si21xx_get_property,
919 .set_frontend = si21xx_set_frontend,
920};
921
922struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
923 struct i2c_adapter *i2c)
924{
925 struct si21xx_state *state = NULL;
926 int id;
927
928 dprintk("%s\n", __func__);
929
930 /* allocate memory for the internal state */
Matthias Schwarzott084e24a2009-08-10 22:51:01 -0300931 state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
Igor M. Liplianin04ad28c2008-09-16 18:21:11 -0300932 if (state == NULL)
933 goto error;
934
935 /* setup the state */
936 state->config = config;
937 state->i2c = i2c;
938 state->initialised = 0;
939 state->errmode = STATUS_BER;
940
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);
946
947 /* register 0x00 contains:
948 0x34 for SI2107
949 0x24 for SI2108
950 0x14 for SI2109
951 0x04 for SI2110
952 */
953 if (id != 0x04 && id != 0x14)
954 goto error;
955
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;
961
962error:
963 kfree(state);
964 return NULL;
965}
966EXPORT_SYMBOL(si21xx_attach);
967
968module_param(debug, int, 0644);
969MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
970
971MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
972MODULE_AUTHOR("Igor M. Liplianin");
973MODULE_LICENSE("GPL");