]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/media/dvb-frontends/si21xx.c
UBUNTU: Ubuntu-5.15.0-39.42
[mirror_ubuntu-jammy-kernel.git] / drivers / media / dvb-frontends / si21xx.c
CommitLineData
2874c5fd 1// SPDX-License-Identifier: GPL-2.0-or-later
04ad28c9
IL
2/* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
3*
4* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
04ad28c9 5*/
04ad28c9
IL
6#include <linux/init.h>
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/string.h>
10#include <linux/slab.h>
11#include <linux/jiffies.h>
12#include <asm/div64.h>
13
fada1935 14#include <media/dvb_frontend.h>
04ad28c9
IL
15#include "si21xx.h"
16
17#define REVISION_REG 0x00
18#define SYSTEM_MODE_REG 0x01
19#define TS_CTRL_REG_1 0x02
20#define TS_CTRL_REG_2 0x03
21#define PIN_CTRL_REG_1 0x04
22#define PIN_CTRL_REG_2 0x05
23#define LOCK_STATUS_REG_1 0x0f
24#define LOCK_STATUS_REG_2 0x10
25#define ACQ_STATUS_REG 0x11
26#define ACQ_CTRL_REG_1 0x13
27#define ACQ_CTRL_REG_2 0x14
28#define PLL_DIVISOR_REG 0x15
29#define COARSE_TUNE_REG 0x16
30#define FINE_TUNE_REG_L 0x17
31#define FINE_TUNE_REG_H 0x18
32
33#define ANALOG_AGC_POWER_LEVEL_REG 0x28
34#define CFO_ESTIMATOR_CTRL_REG_1 0x29
35#define CFO_ESTIMATOR_CTRL_REG_2 0x2a
36#define CFO_ESTIMATOR_CTRL_REG_3 0x2b
37
38#define SYM_RATE_ESTIMATE_REG_L 0x31
39#define SYM_RATE_ESTIMATE_REG_M 0x32
40#define SYM_RATE_ESTIMATE_REG_H 0x33
41
42#define CFO_ESTIMATOR_OFFSET_REG_L 0x36
43#define CFO_ESTIMATOR_OFFSET_REG_H 0x37
44#define CFO_ERROR_REG_L 0x38
45#define CFO_ERROR_REG_H 0x39
46#define SYM_RATE_ESTIMATOR_CTRL_REG 0x3a
47
48#define SYM_RATE_REG_L 0x3f
49#define SYM_RATE_REG_M 0x40
50#define SYM_RATE_REG_H 0x41
51#define SYM_RATE_ESTIMATOR_MAXIMUM_REG 0x42
52#define SYM_RATE_ESTIMATOR_MINIMUM_REG 0x43
53
54#define C_N_ESTIMATOR_CTRL_REG 0x7c
55#define C_N_ESTIMATOR_THRSHLD_REG 0x7d
56#define C_N_ESTIMATOR_LEVEL_REG_L 0x7e
57#define C_N_ESTIMATOR_LEVEL_REG_H 0x7f
58
59#define BLIND_SCAN_CTRL_REG 0x80
60
61#define LSA_CTRL_REG_1 0x8D
62#define SPCTRM_TILT_CORR_THRSHLD_REG 0x8f
63#define ONE_DB_BNDWDTH_THRSHLD_REG 0x90
64#define TWO_DB_BNDWDTH_THRSHLD_REG 0x91
65#define THREE_DB_BNDWDTH_THRSHLD_REG 0x92
66#define INBAND_POWER_THRSHLD_REG 0x93
67#define REF_NOISE_LVL_MRGN_THRSHLD_REG 0x94
68
69#define VIT_SRCH_CTRL_REG_1 0xa0
70#define VIT_SRCH_CTRL_REG_2 0xa1
71#define VIT_SRCH_CTRL_REG_3 0xa2
72#define VIT_SRCH_STATUS_REG 0xa3
73#define VITERBI_BER_COUNT_REG_L 0xab
74#define REED_SOLOMON_CTRL_REG 0xb0
75#define REED_SOLOMON_ERROR_COUNT_REG_L 0xb1
76#define PRBS_CTRL_REG 0xb5
77
78#define LNB_CTRL_REG_1 0xc0
79#define LNB_CTRL_REG_2 0xc1
80#define LNB_CTRL_REG_3 0xc2
81#define LNB_CTRL_REG_4 0xc3
82#define LNB_CTRL_STATUS_REG 0xc4
83#define LNB_FIFO_REGS_0 0xc5
84#define LNB_FIFO_REGS_1 0xc6
85#define LNB_FIFO_REGS_2 0xc7
86#define LNB_FIFO_REGS_3 0xc8
87#define LNB_FIFO_REGS_4 0xc9
88#define LNB_FIFO_REGS_5 0xca
89#define LNB_SUPPLY_CTRL_REG_1 0xcb
90#define LNB_SUPPLY_CTRL_REG_2 0xcc
91#define LNB_SUPPLY_CTRL_REG_3 0xcd
92#define LNB_SUPPLY_CTRL_REG_4 0xce
93#define LNB_SUPPLY_STATUS_REG 0xcf
94
04ad28c9
IL
95#define FAIL -1
96#define PASS 0
97
98#define ALLOWABLE_FS_COUNT 10
99#define STATUS_BER 0
100#define STATUS_UCBLOCKS 1
101
102static int debug;
103#define dprintk(args...) \
104 do { \
105 if (debug) \
106 printk(KERN_DEBUG "si21xx: " args); \
107 } while (0)
108
109enum {
110 ACTIVE_HIGH,
111 ACTIVE_LOW
112};
113enum {
114 BYTE_WIDE,
115 BIT_WIDE
116};
117enum {
118 CLK_GAPPED_MODE,
119 CLK_CONTINUOUS_MODE
120};
121enum {
122 RISING_EDGE,
123 FALLING_EDGE
124};
125enum {
126 MSB_FIRST,
127 LSB_FIRST
128};
129enum {
130 SERIAL,
131 PARALLEL
132};
133
134struct si21xx_state {
135 struct i2c_adapter *i2c;
136 const struct si21xx_config *config;
137 struct dvb_frontend frontend;
138 u8 initialised:1;
139 int errmode;
140 int fs; /*Sampling rate of the ADC in MHz*/
141};
142
143/* register default initialization */
144static u8 serit_sp1511lhb_inittab[] = {
145 0x01, 0x28, /* set i2c_inc_disable */
146 0x20, 0x03,
147 0x27, 0x20,
148 0xe0, 0x45,
149 0xe1, 0x08,
150 0xfe, 0x01,
151 0x01, 0x28,
152 0x89, 0x09,
153 0x04, 0x80,
154 0x05, 0x01,
155 0x06, 0x00,
156 0x20, 0x03,
157 0x24, 0x88,
158 0x29, 0x09,
159 0x2a, 0x0f,
160 0x2c, 0x10,
161 0x2d, 0x19,
162 0x2e, 0x08,
163 0x2f, 0x10,
164 0x30, 0x19,
165 0x34, 0x20,
166 0x35, 0x03,
167 0x45, 0x02,
168 0x46, 0x45,
169 0x47, 0xd0,
170 0x48, 0x00,
171 0x49, 0x40,
172 0x4a, 0x03,
173 0x4c, 0xfd,
174 0x4f, 0x2e,
175 0x50, 0x2e,
176 0x51, 0x10,
177 0x52, 0x10,
178 0x56, 0x92,
179 0x59, 0x00,
180 0x5a, 0x2d,
181 0x5b, 0x33,
182 0x5c, 0x1f,
183 0x5f, 0x76,
184 0x62, 0xc0,
185 0x63, 0xc0,
186 0x64, 0xf3,
187 0x65, 0xf3,
188 0x79, 0x40,
189 0x6a, 0x40,
190 0x6b, 0x0a,
191 0x6c, 0x80,
192 0x6d, 0x27,
193 0x71, 0x06,
194 0x75, 0x60,
195 0x78, 0x00,
196 0x79, 0xb5,
197 0x7c, 0x05,
198 0x7d, 0x1a,
199 0x87, 0x55,
200 0x88, 0x72,
201 0x8f, 0x08,
202 0x90, 0xe0,
203 0x94, 0x40,
204 0xa0, 0x3f,
205 0xa1, 0xc0,
206 0xa4, 0xcc,
207 0xa5, 0x66,
208 0xa6, 0x66,
209 0xa7, 0x7b,
210 0xa8, 0x7b,
211 0xa9, 0x7b,
212 0xaa, 0x9a,
213 0xed, 0x04,
214 0xad, 0x00,
215 0xae, 0x03,
216 0xcc, 0xab,
217 0x01, 0x08,
218 0xff, 0xff
219};
220
221/* low level read/writes */
222static int si21_writeregs(struct si21xx_state *state, u8 reg1,
223 u8 *data, int len)
224{
225 int ret;
226 u8 buf[60];/* = { reg1, data };*/
227 struct i2c_msg msg = {
228 .addr = state->config->demod_address,
229 .flags = 0,
230 .buf = buf,
231 .len = len + 1
232 };
233
cf3b576d
DC
234 if (len > sizeof(buf) - 1)
235 return -EINVAL;
236
04ad28c9
IL
237 msg.buf[0] = reg1;
238 memcpy(msg.buf + 1, data, len);
239
240 ret = i2c_transfer(state->i2c, &msg, 1);
241
242 if (ret != 1)
4bd69e7b
MCC
243 dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, ret == %i)\n",
244 __func__, reg1, data[0], ret);
04ad28c9
IL
245
246 return (ret != 1) ? -EREMOTEIO : 0;
247}
248
249static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
250{
251 int ret;
252 u8 buf[] = { reg, data };
253 struct i2c_msg msg = {
254 .addr = state->config->demod_address,
255 .flags = 0,
256 .buf = buf,
257 .len = 2
258 };
259
260 ret = i2c_transfer(state->i2c, &msg, 1);
261
262 if (ret != 1)
4bd69e7b
MCC
263 dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, ret == %i)\n",
264 __func__, reg, data, ret);
04ad28c9
IL
265
266 return (ret != 1) ? -EREMOTEIO : 0;
267}
268
2e4e98e7 269static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len)
04ad28c9
IL
270{
271 struct si21xx_state *state = fe->demodulator_priv;
272
273 if (len != 2)
274 return -EINVAL;
275
276 return si21_writereg(state, buf[0], buf[1]);
277}
278
279static u8 si21_readreg(struct si21xx_state *state, u8 reg)
280{
281 int ret;
282 u8 b0[] = { reg };
283 u8 b1[] = { 0 };
284 struct i2c_msg msg[] = {
285 {
286 .addr = state->config->demod_address,
287 .flags = 0,
288 .buf = b0,
289 .len = 1
290 }, {
291 .addr = state->config->demod_address,
292 .flags = I2C_M_RD,
293 .buf = b1,
294 .len = 1
295 }
296 };
297
298 ret = i2c_transfer(state->i2c, msg, 2);
299
300 if (ret != 2)
301 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
302 __func__, reg, ret);
303
304 return b1[0];
305}
306
307static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
308{
309 int ret;
310 struct i2c_msg msg[] = {
311 {
312 .addr = state->config->demod_address,
313 .flags = 0,
314 .buf = &reg1,
315 .len = 1
316 }, {
317 .addr = state->config->demod_address,
318 .flags = I2C_M_RD,
319 .buf = b,
320 .len = len
321 }
322 };
323
324 ret = i2c_transfer(state->i2c, msg, 2);
325
326 if (ret != 2)
327 dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
328
329 return ret == 2 ? 0 : -1;
330}
331
332static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
333{
334 unsigned long start = jiffies;
335
336 dprintk("%s\n", __func__);
337
338 while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
339 if (jiffies - start > timeout) {
340 dprintk("%s: timeout!!\n", __func__);
341 return -ETIMEDOUT;
342 }
343 msleep(10);
c2c1b415 344 }
04ad28c9
IL
345
346 return 0;
347}
348
349static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
350{
351 struct si21xx_state *state = fe->demodulator_priv;
352 u32 sym_rate, data_rate;
353 int i;
354 u8 sym_rate_bytes[3];
355
356 dprintk("%s : srate = %i\n", __func__ , srate);
357
358 if ((srate < 1000000) || (srate > 45000000))
359 return -EINVAL;
360
361 data_rate = srate;
362 sym_rate = 0;
363
364 for (i = 0; i < 4; ++i) {
365 sym_rate /= 100;
366 sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
367 state->fs;
368 data_rate /= 100;
369 }
370 for (i = 0; i < 3; ++i)
371 sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
372
373 si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
374
375 return 0;
376}
377
378static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
379 struct dvb_diseqc_master_cmd *m)
380{
381 struct si21xx_state *state = fe->demodulator_priv;
382 u8 lnb_status;
383 u8 LNB_CTRL_1;
384 int status;
385
386 dprintk("%s\n", __func__);
387
388 status = PASS;
389 LNB_CTRL_1 = 0;
390
391 status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
392 status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
393
394 /*fill the FIFO*/
395 status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
396
397 LNB_CTRL_1 = (lnb_status & 0x70);
398 LNB_CTRL_1 |= m->msg_len;
399
400 LNB_CTRL_1 |= 0x80; /* begin LNB signaling */
401
402 status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
403
404 return status;
405}
406
407static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
0df289a2 408 enum fe_sec_mini_cmd burst)
04ad28c9
IL
409{
410 struct si21xx_state *state = fe->demodulator_priv;
411 u8 val;
412
413 dprintk("%s\n", __func__);
414
415 if (si21xx_wait_diseqc_idle(state, 100) < 0)
416 return -ETIMEDOUT;
417
418 val = (0x80 | si21_readreg(state, 0xc1));
419 if (si21_writereg(state, LNB_CTRL_REG_1,
420 burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
421 return -EREMOTEIO;
422
423 if (si21xx_wait_diseqc_idle(state, 100) < 0)
424 return -ETIMEDOUT;
425
426 if (si21_writereg(state, LNB_CTRL_REG_1, val))
427 return -EREMOTEIO;
428
429 return 0;
430}
431/* 30.06.2008 */
0df289a2 432static int si21xx_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
04ad28c9
IL
433{
434 struct si21xx_state *state = fe->demodulator_priv;
435 u8 val;
436
437 dprintk("%s\n", __func__);
438 val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
439
440 switch (tone) {
441 case SEC_TONE_ON:
442 return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
443
444 case SEC_TONE_OFF:
445 return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
446
447 default:
448 return -EINVAL;
449 }
450}
451
0df289a2 452static int si21xx_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage volt)
04ad28c9
IL
453{
454 struct si21xx_state *state = fe->demodulator_priv;
455
456 u8 val;
457 dprintk("%s: %s\n", __func__,
458 volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
459 volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
460
461
462 val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
463
464 switch (volt) {
465 case SEC_VOLTAGE_18:
466 return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
04ad28c9
IL
467 case SEC_VOLTAGE_13:
468 return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
04ad28c9
IL
469 default:
470 return -EINVAL;
c2c1b415 471 }
04ad28c9
IL
472}
473
474static int si21xx_init(struct dvb_frontend *fe)
475{
476 struct si21xx_state *state = fe->demodulator_priv;
477 int i;
478 int status = 0;
479 u8 reg1;
480 u8 val;
481 u8 reg2[2];
482
483 dprintk("%s\n", __func__);
484
485 for (i = 0; ; i += 2) {
486 reg1 = serit_sp1511lhb_inittab[i];
487 val = serit_sp1511lhb_inittab[i+1];
488 if (reg1 == 0xff && val == 0xff)
489 break;
490 si21_writeregs(state, reg1, &val, 1);
491 }
492
493 /*DVB QPSK SYSTEM MODE REG*/
494 reg1 = 0x08;
495 si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
496
497 /*transport stream config*/
498 /*
499 mode = PARALLEL;
500 sdata_form = LSB_FIRST;
501 clk_edge = FALLING_EDGE;
502 clk_mode = CLK_GAPPED_MODE;
503 strt_len = BYTE_WIDE;
504 sync_pol = ACTIVE_HIGH;
505 val_pol = ACTIVE_HIGH;
506 err_pol = ACTIVE_HIGH;
507 sclk_rate = 0x00;
508 parity = 0x00 ;
509 data_delay = 0x00;
510 clk_delay = 0x00;
511 pclk_smooth = 0x00;
512 */
513 reg2[0] =
514 PARALLEL + (LSB_FIRST << 1)
515 + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
516 + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
517 + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
518
519 reg2[1] = 0;
520 /* sclk_rate + (parity << 2)
521 + (data_delay << 3) + (clk_delay << 4)
522 + (pclk_smooth << 5);
523 */
524 status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
525 if (status != 0)
526 dprintk(" %s : TS Set Error\n", __func__);
527
528 return 0;
529
530}
531
0df289a2 532static int si21_read_status(struct dvb_frontend *fe, enum fe_status *status)
04ad28c9
IL
533{
534 struct si21xx_state *state = fe->demodulator_priv;
535 u8 regs_read[2];
536 u8 reg_read;
537 u8 i;
538 u8 lock;
539 u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
540
541 si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
542 reg_read = 0;
543
544 for (i = 0; i < 7; ++i)
545 reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
546
547 lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
548
549 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
550 *status = 0;
551
552 if (signal > 10)
553 *status |= FE_HAS_SIGNAL;
554
555 if (lock & 0x2)
556 *status |= FE_HAS_CARRIER;
557
558 if (lock & 0x20)
559 *status |= FE_HAS_VITERBI;
560
561 if (lock & 0x40)
562 *status |= FE_HAS_SYNC;
563
564 if ((lock & 0x7b) == 0x7b)
565 *status |= FE_HAS_LOCK;
566
567 return 0;
568}
569
570static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
571{
572 struct si21xx_state *state = fe->demodulator_priv;
573
574 /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
575 (u8*)agclevel, 0x01);*/
576
577 u16 signal = (3 * si21_readreg(state, 0x27) *
578 si21_readreg(state, 0x28));
579
580 dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
581 si21_readreg(state, 0x27),
582 si21_readreg(state, 0x28), (int) signal);
583
584 signal <<= 4;
585 *strength = signal;
586
587 return 0;
588}
589
590static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
591{
592 struct si21xx_state *state = fe->demodulator_priv;
593
594 dprintk("%s\n", __func__);
595
596 if (state->errmode != STATUS_BER)
597 return 0;
598
599 *ber = (si21_readreg(state, 0x1d) << 8) |
600 si21_readreg(state, 0x1e);
601
602 return 0;
603}
604
605static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
606{
607 struct si21xx_state *state = fe->demodulator_priv;
608
609 s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
610 si21_readreg(state, 0x25));
611 xsnr = 3 * (xsnr - 0xa100);
612 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
613
614 dprintk("%s\n", __func__);
615
616 return 0;
617}
618
619static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
620{
621 struct si21xx_state *state = fe->demodulator_priv;
622
623 dprintk("%s\n", __func__);
624
625 if (state->errmode != STATUS_UCBLOCKS)
626 *ucblocks = 0;
627 else
628 *ucblocks = (si21_readreg(state, 0x1d) << 8) |
629 si21_readreg(state, 0x1e);
630
631 return 0;
632}
633
634/* initiates a channel acquisition sequence
635 using the specified symbol rate and code rate */
636static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
0df289a2 637 enum fe_code_rate crate)
04ad28c9
IL
638{
639
640 struct si21xx_state *state = fe->demodulator_priv;
641 u8 coderates[] = {
642 0x0, 0x01, 0x02, 0x04, 0x00,
643 0x8, 0x10, 0x20, 0x00, 0x3f
644 };
645
646 u8 coderate_ptr;
647 int status;
648 u8 start_acq = 0x80;
649 u8 reg, regs[3];
650
651 dprintk("%s\n", __func__);
652
653 status = PASS;
654 coderate_ptr = coderates[crate];
655
656 si21xx_set_symbolrate(fe, symbrate);
657
658 /* write code rates to use in the Viterbi search */
659 status |= si21_writeregs(state,
660 VIT_SRCH_CTRL_REG_1,
661 &coderate_ptr, 0x01);
662
663 /* clear acq_start bit */
664 status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
665 reg &= ~start_acq;
666 status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
667
668 /* use new Carrier Frequency Offset Estimator (QuickLock) */
669 regs[0] = 0xCB;
670 regs[1] = 0x40;
671 regs[2] = 0xCB;
672
673 status |= si21_writeregs(state,
674 TWO_DB_BNDWDTH_THRSHLD_REG,
675 &regs[0], 0x03);
676 reg = 0x56;
677 status |= si21_writeregs(state,
678 LSA_CTRL_REG_1, &reg, 1);
679 reg = 0x05;
680 status |= si21_writeregs(state,
681 BLIND_SCAN_CTRL_REG, &reg, 1);
682 /* start automatic acq */
683 status |= si21_writeregs(state,
684 ACQ_CTRL_REG_2, &start_acq, 0x01);
685
686 return status;
687}
688
14e3dcca 689static int si21xx_set_frontend(struct dvb_frontend *fe)
04ad28c9
IL
690{
691 struct si21xx_state *state = fe->demodulator_priv;
692 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
693
694 /* freq Channel carrier frequency in KHz (i.e. 1550000 KHz)
695 datarate Channel symbol rate in Sps (i.e. 22500000 Sps)*/
696
697 /* in MHz */
698 unsigned char coarse_tune_freq;
699 int fine_tune_freq;
700 unsigned char sample_rate = 0;
701 /* boolean */
42a39e05 702 bool inband_interferer_ind;
04ad28c9
IL
703
704 /* INTERMEDIATE VALUES */
705 int icoarse_tune_freq; /* MHz */
706 int ifine_tune_freq; /* MHz */
707 unsigned int band_high;
708 unsigned int band_low;
709 unsigned int x1;
710 unsigned int x2;
711 int i;
42a39e05
JP
712 bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
713 bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
04ad28c9
IL
714 int status;
715
716 /* allowable sample rates for ADC in MHz */
717 int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
718 196, 204, 205, 206, 207
719 };
720 /* in MHz */
721 int if_limit_high;
722 int if_limit_low;
723 int lnb_lo;
724 int lnb_uncertanity;
725
726 int rf_freq;
727 int data_rate;
728 unsigned char regs[4];
729
730 dprintk("%s : FE_SET_FRONTEND\n", __func__);
731
732 if (c->delivery_system != SYS_DVBS) {
733 dprintk("%s: unsupported delivery system selected (%d)\n",
734 __func__, c->delivery_system);
735 return -EOPNOTSUPP;
736 }
737
738 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
42a39e05 739 inband_interferer_div2[i] = inband_interferer_div4[i] = false;
04ad28c9
IL
740
741 if_limit_high = -700000;
742 if_limit_low = -100000;
743 /* in MHz */
744 lnb_lo = 0;
745 lnb_uncertanity = 0;
746
747 rf_freq = 10 * c->frequency ;
748 data_rate = c->symbol_rate / 100;
749
750 status = PASS;
751
752 band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
753 + (data_rate * 135)) / 200;
754
755 band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
756 + (data_rate * 135)) / 200;
757
758
759 icoarse_tune_freq = 100000 *
760 (((rf_freq - lnb_lo) -
761 (if_limit_low + if_limit_high) / 2)
762 / 100000);
763
764 ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
765
766 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
767 x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
768 (afs[i] * 2500) + afs[i] * 2500;
769
770 x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
771 (afs[i] * 2500);
772
773 if (((band_low < x1) && (x1 < band_high)) ||
774 ((band_low < x2) && (x2 < band_high)))
42a39e05 775 inband_interferer_div4[i] = true;
04ad28c9
IL
776
777 }
778
779 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
780 x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
781 (afs[i] * 5000) + afs[i] * 5000;
782
783 x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
784 (afs[i] * 5000);
785
786 if (((band_low < x1) && (x1 < band_high)) ||
787 ((band_low < x2) && (x2 < band_high)))
42a39e05 788 inband_interferer_div2[i] = true;
04ad28c9
IL
789 }
790
42a39e05
JP
791 inband_interferer_ind = true;
792 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
793 if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
794 inband_interferer_ind = false;
795 break;
796 }
797 }
04ad28c9
IL
798
799 if (inband_interferer_ind) {
800 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
42a39e05 801 if (!inband_interferer_div2[i]) {
04ad28c9
IL
802 sample_rate = (u8) afs[i];
803 break;
804 }
805 }
806 } else {
807 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
42a39e05
JP
808 if ((inband_interferer_div2[i] ||
809 !inband_interferer_div4[i])) {
04ad28c9
IL
810 sample_rate = (u8) afs[i];
811 break;
812 }
813 }
814
815 }
816
817 if (sample_rate > 207 || sample_rate < 192)
818 sample_rate = 200;
819
820 fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
821 ((sample_rate) * 1000));
822
823 coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
824
825 regs[0] = sample_rate;
826 regs[1] = coarse_tune_freq;
827 regs[2] = fine_tune_freq & 0xFF;
828 regs[3] = fine_tune_freq >> 8 & 0xFF;
829
830 status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
831
832 state->fs = sample_rate;/*ADC MHz*/
833 si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
834
835 return 0;
836}
837
838static int si21xx_sleep(struct dvb_frontend *fe)
839{
840 struct si21xx_state *state = fe->demodulator_priv;
841 u8 regdata;
842
843 dprintk("%s\n", __func__);
844
845 si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
846 regdata |= 1 << 6;
847 si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
848 state->initialised = 0;
849
850 return 0;
851}
852
853static void si21xx_release(struct dvb_frontend *fe)
854{
855 struct si21xx_state *state = fe->demodulator_priv;
856
857 dprintk("%s\n", __func__);
858
859 kfree(state);
860}
861
bd336e63 862static const struct dvb_frontend_ops si21xx_ops = {
14e3dcca 863 .delsys = { SYS_DVBS },
04ad28c9
IL
864 .info = {
865 .name = "SL SI21XX DVB-S",
f1b1eabf
MCC
866 .frequency_min_hz = 950 * MHz,
867 .frequency_max_hz = 2150 * MHz,
868 .frequency_stepsize_hz = 125 * kHz,
04ad28c9
IL
869 .symbol_rate_min = 1000000,
870 .symbol_rate_max = 45000000,
871 .symbol_rate_tolerance = 500, /* ppm */
872 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
873 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
874 FE_CAN_QPSK |
875 FE_CAN_FEC_AUTO
876 },
877
878 .release = si21xx_release,
879 .init = si21xx_init,
880 .sleep = si21xx_sleep,
881 .write = si21_write,
882 .read_status = si21_read_status,
883 .read_ber = si21_read_ber,
884 .read_signal_strength = si21_read_signal_strength,
885 .read_snr = si21_read_snr,
886 .read_ucblocks = si21_read_ucblocks,
887 .diseqc_send_master_cmd = si21xx_send_diseqc_msg,
888 .diseqc_send_burst = si21xx_send_diseqc_burst,
889 .set_tone = si21xx_set_tone,
890 .set_voltage = si21xx_set_voltage,
891
14e3dcca 892 .set_frontend = si21xx_set_frontend,
04ad28c9
IL
893};
894
895struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
896 struct i2c_adapter *i2c)
897{
898 struct si21xx_state *state = NULL;
899 int id;
900
901 dprintk("%s\n", __func__);
902
903 /* allocate memory for the internal state */
084e24ac 904 state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
04ad28c9
IL
905 if (state == NULL)
906 goto error;
907
908 /* setup the state */
909 state->config = config;
910 state->i2c = i2c;
911 state->initialised = 0;
912 state->errmode = STATUS_BER;
913
914 /* check if the demod is there */
915 id = si21_readreg(state, SYSTEM_MODE_REG);
916 si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
917 msleep(200);
918 id = si21_readreg(state, 0x00);
919
920 /* register 0x00 contains:
921 0x34 for SI2107
922 0x24 for SI2108
923 0x14 for SI2109
924 0x04 for SI2110
925 */
926 if (id != 0x04 && id != 0x14)
927 goto error;
928
929 /* create dvb_frontend */
930 memcpy(&state->frontend.ops, &si21xx_ops,
931 sizeof(struct dvb_frontend_ops));
932 state->frontend.demodulator_priv = state;
933 return &state->frontend;
934
935error:
936 kfree(state);
937 return NULL;
938}
939EXPORT_SYMBOL(si21xx_attach);
940
941module_param(debug, int, 0644);
942MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
943
944MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
945MODULE_AUTHOR("Igor M. Liplianin");
946MODULE_LICENSE("GPL");