xref: /linux/drivers/media/dvb-frontends/si21xx.c (revision 4fd18fc38757217c746aa063ba9e4729814dc737)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
3 *
4 * Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
5 */
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 
14 #include <media/dvb_frontend.h>
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 
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 
102 static int debug;
103 #define dprintk(args...) \
104 	do { \
105 		if (debug) \
106 			printk(KERN_DEBUG "si21xx: " args); \
107 	} while (0)
108 
109 enum {
110 	ACTIVE_HIGH,
111 	ACTIVE_LOW
112 };
113 enum {
114 	BYTE_WIDE,
115 	BIT_WIDE
116 };
117 enum {
118 	CLK_GAPPED_MODE,
119 	CLK_CONTINUOUS_MODE
120 };
121 enum {
122 	RISING_EDGE,
123 	FALLING_EDGE
124 };
125 enum {
126 	MSB_FIRST,
127 	LSB_FIRST
128 };
129 enum {
130 	SERIAL,
131 	PARALLEL
132 };
133 
134 struct 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 */
144 static 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 */
222 static 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 
234 	if (len > sizeof(buf) - 1)
235 		return -EINVAL;
236 
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)
243 		dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, ret == %i)\n",
244 			__func__, reg1, data[0], ret);
245 
246 	return (ret != 1) ? -EREMOTEIO : 0;
247 }
248 
249 static 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)
263 		dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, ret == %i)\n",
264 			__func__, reg, data, ret);
265 
266 	return (ret != 1) ? -EREMOTEIO : 0;
267 }
268 
269 static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len)
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 
279 static 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 
307 static 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 
332 static 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);
344 	}
345 
346 	return 0;
347 }
348 
349 static 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 
378 static 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 
407 static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
408 				    enum fe_sec_mini_cmd burst)
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 */
432 static int si21xx_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
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 
452 static int si21xx_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage volt)
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);
467 	case SEC_VOLTAGE_13:
468 		return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
469 	default:
470 		return -EINVAL;
471 	}
472 }
473 
474 static 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 
532 static int si21_read_status(struct dvb_frontend *fe, enum fe_status *status)
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 
570 static 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 
590 static 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 
605 static 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 
619 static 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 */
636 static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
637 			     enum fe_code_rate crate)
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 
689 static int si21xx_set_frontend(struct dvb_frontend *fe)
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 */
702 	bool inband_interferer_ind;
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;
712 	bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
713 	bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
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)
739 		inband_interferer_div2[i] = inband_interferer_div4[i] = false;
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)))
775 					inband_interferer_div4[i] = true;
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)))
788 					inband_interferer_div2[i] = true;
789 	}
790 
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 	}
798 
799 	if (inband_interferer_ind) {
800 		for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
801 			if (!inband_interferer_div2[i]) {
802 				sample_rate = (u8) afs[i];
803 				break;
804 			}
805 		}
806 	} else {
807 		for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
808 			if ((inband_interferer_div2[i] ||
809 			     !inband_interferer_div4[i])) {
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 
838 static 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 
853 static 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 
862 static const struct dvb_frontend_ops si21xx_ops = {
863 	.delsys = { SYS_DVBS },
864 	.info = {
865 		.name			= "SL SI21XX DVB-S",
866 		.frequency_min_hz	=  950 * MHz,
867 		.frequency_max_hz	= 2150 * MHz,
868 		.frequency_stepsize_hz	=  125 * kHz,
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 
892 	.set_frontend = si21xx_set_frontend,
893 };
894 
895 struct 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 */
904 	state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
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 
935 error:
936 	kfree(state);
937 	return NULL;
938 }
939 EXPORT_SYMBOL(si21xx_attach);
940 
941 module_param(debug, int, 0644);
942 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
943 
944 MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
945 MODULE_AUTHOR("Igor M. Liplianin");
946 MODULE_LICENSE("GPL");
947