PageRenderTime 59ms CodeModel.GetById 30ms app.highlight 24ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/media/dvb/frontends/si21xx.c

https://bitbucket.org/ndreys/linux-sunxi
C | 967 lines | 727 code | 179 blank | 61 comment | 77 complexity | 165b2a045a697ff0261ea1c048eed92e MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1/* 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*/
 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>
 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 FAIL	-1
101#define PASS	0
102
103#define ALLOWABLE_FS_COUNT	10
104#define STATUS_BER		0
105#define STATUS_UCBLOCKS		1
106
107static int debug;
108#define dprintk(args...) \
109	do { \
110		if (debug) \
111			printk(KERN_DEBUG "si21xx: " args); \
112	} while (0)
113
114enum {
115	ACTIVE_HIGH,
116	ACTIVE_LOW
117};
118enum {
119	BYTE_WIDE,
120	BIT_WIDE
121};
122enum {
123	CLK_GAPPED_MODE,
124	CLK_CONTINUOUS_MODE
125};
126enum {
127	RISING_EDGE,
128	FALLING_EDGE
129};
130enum {
131	MSB_FIRST,
132	LSB_FIRST
133};
134enum {
135	SERIAL,
136	PARALLEL
137};
138
139struct 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*/
146};
147
148/*	register default initialization */
149static 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
224};
225
226/*	low level read/writes */
227static int si21_writeregs(struct si21xx_state *state, u8 reg1,
228							u8 *data, int len)
229{
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
237	};
238
239	msg.buf[0] =  reg1;
240	memcpy(msg.buf + 1, data, len);
241
242	ret = i2c_transfer(state->i2c, &msg, 1);
243
244	if (ret != 1)
245		dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, "
246			"ret == %i)\n", __func__, reg1, data[0], ret);
247
248	return (ret != 1) ? -EREMOTEIO : 0;
249}
250
251static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
252{
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
260	};
261
262	ret = i2c_transfer(state->i2c, &msg, 1);
263
264	if (ret != 1)
265		dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, "
266			"ret == %i)\n", __func__, reg, data, ret);
267
268	return (ret != 1) ? -EREMOTEIO : 0;
269}
270
271static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len)
272{
273	struct si21xx_state *state = fe->demodulator_priv;
274
275	if (len != 2)
276		return -EINVAL;
277
278	return si21_writereg(state, buf[0], buf[1]);
279}
280
281static u8 si21_readreg(struct si21xx_state *state, u8 reg)
282{
283	int ret;
284	u8 b0[] = { reg };
285	u8 b1[] = { 0 };
286	struct i2c_msg msg[] = {
287		{
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
297		}
298	};
299
300	ret = i2c_transfer(state->i2c, msg, 2);
301
302	if (ret != 2)
303		dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
304			__func__, reg, ret);
305
306	return b1[0];
307}
308
309static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
310{
311	int ret;
312	struct i2c_msg msg[] = {
313		{
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
323		}
324	};
325
326	ret = i2c_transfer(state->i2c, msg, 2);
327
328	if (ret != 2)
329		dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
330
331	return ret == 2 ? 0 : -1;
332}
333
334static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
335{
336	unsigned long start = jiffies;
337
338	dprintk("%s\n", __func__);
339
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;
344		}
345		msleep(10);
346	};
347
348	return 0;
349}
350
351static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
352{
353	struct si21xx_state *state = fe->demodulator_priv;
354	u32 sym_rate, data_rate;
355	int i;
356	u8 sym_rate_bytes[3];
357
358	dprintk("%s : srate = %i\n", __func__ , srate);
359
360	if ((srate < 1000000) || (srate > 45000000))
361		return -EINVAL;
362
363	data_rate = srate;
364	sym_rate = 0;
365
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;
371	}
372	for (i = 0; i < 3; ++i)
373		sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
374
375	si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
376
377	return 0;
378}
379
380static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
381					struct dvb_diseqc_master_cmd *m)
382{
383	struct si21xx_state *state = fe->demodulator_priv;
384	u8 lnb_status;
385	u8 LNB_CTRL_1;
386	int status;
387
388	dprintk("%s\n", __func__);
389
390	status = PASS;
391	LNB_CTRL_1 = 0;
392
393	status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
394	status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
395
396	/*fill the FIFO*/
397	status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
398
399	LNB_CTRL_1 = (lnb_status & 0x70);
400	LNB_CTRL_1 |= m->msg_len;
401
402	LNB_CTRL_1 |= 0x80;	/* begin LNB signaling */
403
404	status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
405
406	return status;
407}
408
409static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
410						fe_sec_mini_cmd_t burst)
411{
412	struct si21xx_state *state = fe->demodulator_priv;
413	u8 val;
414
415	dprintk("%s\n", __func__);
416
417	if (si21xx_wait_diseqc_idle(state, 100) < 0)
418		return -ETIMEDOUT;
419
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;
424
425	if (si21xx_wait_diseqc_idle(state, 100) < 0)
426		return -ETIMEDOUT;
427
428	if (si21_writereg(state, LNB_CTRL_REG_1, val))
429		return -EREMOTEIO;
430
431	return 0;
432}
433/*	30.06.2008 */
434static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
435{
436	struct si21xx_state *state = fe->demodulator_priv;
437	u8 val;
438
439	dprintk("%s\n", __func__);
440	val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
441
442	switch (tone) {
443	case SEC_TONE_ON:
444		return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
445
446	case SEC_TONE_OFF:
447		return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
448
449	default:
450		return -EINVAL;
451	}
452}
453
454static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
455{
456	struct si21xx_state *state = fe->demodulator_priv;
457
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" : "??");
462
463
464	val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
465
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;
475	};
476}
477
478static int si21xx_init(struct dvb_frontend *fe)
479{
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];
486
487	dprintk("%s\n", __func__);
488
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);
495	}
496
497	/*DVB QPSK SYSTEM MODE REG*/
498	reg1 = 0x08;
499	si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
500
501	/*transport stream config*/
502	/*
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;
516	*/
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);
522
523	reg2[1] = 0;
524	/*	sclk_rate + (parity << 2)
525		+ (data_delay << 3) + (clk_delay << 4)
526		+ (pclk_smooth << 5);
527	*/
528	status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
529	if (status != 0)
530		dprintk(" %s : TS Set Error\n", __func__);
531
532	return 0;
533
534}
535
536static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status)
537{
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);
544
545	si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
546	reg_read = 0;
547
548	for (i = 0; i < 7; ++i)
549		reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
550
551	lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
552
553	dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
554	*status = 0;
555
556	if (signal > 10)
557		*status |= FE_HAS_SIGNAL;
558
559	if (lock & 0x2)
560		*status |= FE_HAS_CARRIER;
561
562	if (lock & 0x20)
563		*status |= FE_HAS_VITERBI;
564
565	if (lock & 0x40)
566		*status |= FE_HAS_SYNC;
567
568	if ((lock & 0x7b) == 0x7b)
569		*status |= FE_HAS_LOCK;
570
571	return 0;
572}
573
574static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
575{
576	struct si21xx_state *state = fe->demodulator_priv;
577
578	/*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
579						(u8*)agclevel, 0x01);*/
580
581	u16 signal = (3 * si21_readreg(state, 0x27) *
582					si21_readreg(state, 0x28));
583
584	dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
585		si21_readreg(state, 0x27),
586		si21_readreg(state, 0x28), (int) signal);
587
588	signal  <<= 4;
589	*strength = signal;
590
591	return 0;
592}
593
594static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
595{
596	struct si21xx_state *state = fe->demodulator_priv;
597
598	dprintk("%s\n", __func__);
599
600	if (state->errmode != STATUS_BER)
601		return 0;
602
603	*ber = (si21_readreg(state, 0x1d) << 8) |
604				si21_readreg(state, 0x1e);
605
606	return 0;
607}
608
609static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
610{
611	struct si21xx_state *state = fe->demodulator_priv;
612
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;
617
618	dprintk("%s\n", __func__);
619
620	return 0;
621}
622
623static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
624{
625	struct si21xx_state *state = fe->demodulator_priv;
626
627	dprintk("%s\n", __func__);
628
629	if (state->errmode != STATUS_UCBLOCKS)
630		*ucblocks = 0;
631	else
632		*ucblocks = (si21_readreg(state, 0x1d) << 8) |
633					si21_readreg(state, 0x1e);
634
635	return 0;
636}
637
638/*	initiates a channel acquisition sequence
639	using the specified symbol rate and code rate */
640static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
641						fe_code_rate_t crate)
642{
643
644	struct si21xx_state *state = fe->demodulator_priv;
645	u8 coderates[] = {
646				0x0, 0x01, 0x02, 0x04, 0x00,
647				0x8, 0x10, 0x20, 0x00, 0x3f
648	};
649
650	u8 coderate_ptr;
651	int status;
652	u8 start_acq = 0x80;
653	u8 reg, regs[3];
654
655	dprintk("%s\n", __func__);
656
657	status = PASS;
658	coderate_ptr = coderates[crate];
659
660	si21xx_set_symbolrate(fe, symbrate);
661
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);
666
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);
671
672	/* use new Carrier Frequency Offset Estimator (QuickLock) */
673	regs[0] = 0xCB;
674	regs[1] = 0x40;
675	regs[2] = 0xCB;
676
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);
689
690	return status;
691}
692
693static int si21xx_set_property(struct dvb_frontend *fe, struct dtv_property *p)
694{
695	dprintk("%s(..)\n", __func__);
696	return 0;
697}
698
699static int si21xx_get_property(struct dvb_frontend *fe, struct dtv_property *p)
700{
701	dprintk("%s(..)\n", __func__);
702	return 0;
703}
704
705static int si21xx_set_frontend(struct dvb_frontend *fe,
706					struct dvb_frontend_parameters *dfp)
707{
708	struct si21xx_state *state = fe->demodulator_priv;
709	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
710
711	/* freq		Channel carrier frequency in KHz (i.e. 1550000 KHz)
712	 datarate	Channel symbol rate in Sps (i.e. 22500000 Sps)*/
713
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;
720
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;
732
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
736	};
737	/* in MHz */
738	int if_limit_high;
739	int if_limit_low;
740	int lnb_lo;
741	int lnb_uncertanity;
742
743	int rf_freq;
744	int data_rate;
745	unsigned char regs[4];
746
747	dprintk("%s : FE_SET_FRONTEND\n", __func__);
748
749	if (c->delivery_system != SYS_DVBS) {
750			dprintk("%s: unsupported delivery system selected (%d)\n",
751				__func__, c->delivery_system);
752			return -EOPNOTSUPP;
753	}
754
755	for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
756		inband_interferer_div2[i] = inband_interferer_div4[i] = false;
757
758	if_limit_high = -700000;
759	if_limit_low = -100000;
760	/* in MHz */
761	lnb_lo = 0;
762	lnb_uncertanity = 0;
763
764	rf_freq = 10 * c->frequency ;
765	data_rate = c->symbol_rate / 100;
766
767	status = PASS;
768
769	band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
770					+ (data_rate * 135)) / 200;
771
772	band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
773					+ (data_rate * 135)) / 200;
774
775
776	icoarse_tune_freq = 100000 *
777				(((rf_freq - lnb_lo) -
778					(if_limit_low + if_limit_high) / 2)
779								/ 100000);
780
781	ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
782
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;
786
787		x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
788							(afs[i] * 2500);
789
790		if (((band_low < x1) && (x1 < band_high)) ||
791					((band_low < x2) && (x2 < band_high)))
792					inband_interferer_div4[i] = true;
793
794	}
795
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;
799
800		x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
801					(afs[i] * 5000);
802
803		if (((band_low < x1) && (x1 < band_high)) ||
804					((band_low < x2) && (x2 < band_high)))
805					inband_interferer_div2[i] = true;
806	}
807
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;
813		}
814	}
815
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;
821			}
822		}
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;
829			}
830		}
831
832	}
833
834	if (sample_rate > 207 || sample_rate < 192)
835		sample_rate = 200;
836
837	fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
838					((sample_rate) * 1000));
839
840	coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
841
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;
846
847	status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
848
849	state->fs = sample_rate;/*ADC MHz*/
850	si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
851
852	return 0;
853}
854
855static int si21xx_sleep(struct dvb_frontend *fe)
856{
857	struct si21xx_state *state = fe->demodulator_priv;
858	u8 regdata;
859
860	dprintk("%s\n", __func__);
861
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;
866
867	return 0;
868}
869
870static void si21xx_release(struct dvb_frontend *fe)
871{
872	struct si21xx_state *state = fe->demodulator_priv;
873
874	dprintk("%s\n", __func__);
875
876	kfree(state);
877}
878
879static struct dvb_frontend_ops si21xx_ops = {
880
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
895	},
896
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,
910
911	.set_property = si21xx_set_property,
912	.get_property = si21xx_get_property,
913	.set_frontend = si21xx_set_frontend,
914};
915
916struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
917						struct i2c_adapter *i2c)
918{
919	struct si21xx_state *state = NULL;
920	int id;
921
922	dprintk("%s\n", __func__);
923
924	/* allocate memory for the internal state */
925	state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
926	if (state == NULL)
927		goto error;
928
929	/* setup the state */
930	state->config = config;
931	state->i2c = i2c;
932	state->initialised = 0;
933	state->errmode = STATUS_BER;
934
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);
940
941	/* register 0x00 contains:
942		0x34 for SI2107
943		0x24 for SI2108
944		0x14 for SI2109
945		0x04 for SI2110
946	*/
947	if (id != 0x04 && id != 0x14)
948		goto error;
949
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;
955
956error:
957	kfree(state);
958	return NULL;
959}
960EXPORT_SYMBOL(si21xx_attach);
961
962module_param(debug, int, 0644);
963MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
964
965MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
966MODULE_AUTHOR("Igor M. Liplianin");
967MODULE_LICENSE("GPL");