• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/media/dvb/frontends/
1/*
2	Driver for ST STV0288 demodulator
3	Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
4		for Reel Multimedia
5	Copyright (C) 2008 TurboSight.com, Bob Liu <bob@turbosight.com>
6	Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
7		Removed stb6000 specific tuner code and revised some
8		procedures.
9
10	This program is free software; you can redistribute it and/or modify
11	it under the terms of the GNU General Public License as published by
12	the Free Software Foundation; either version 2 of the License, or
13	(at your option) any later version.
14
15	This program is distributed in the hope that it will be useful,
16	but WITHOUT ANY WARRANTY; without even the implied warranty of
17	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18	GNU General Public License for more details.
19
20	You should have received a copy of the GNU General Public License
21	along with this program; if not, write to the Free Software
22	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24*/
25
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/string.h>
30#include <linux/slab.h>
31#include <linux/jiffies.h>
32#include <asm/div64.h>
33
34#include "dvb_frontend.h"
35#include "stv0288.h"
36
37struct stv0288_state {
38	struct i2c_adapter *i2c;
39	const struct stv0288_config *config;
40	struct dvb_frontend frontend;
41
42	u8 initialised:1;
43	u32 tuner_frequency;
44	u32 symbol_rate;
45	fe_code_rate_t fec_inner;
46	int errmode;
47};
48
49#define STATUS_BER 0
50#define STATUS_UCBLOCKS 1
51
52static int debug;
53static int debug_legacy_dish_switch;
54#define dprintk(args...) \
55	do { \
56		if (debug) \
57			printk(KERN_DEBUG "stv0288: " args); \
58	} while (0)
59
60
61static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data)
62{
63	int ret;
64	u8 buf[] = { reg, data };
65	struct i2c_msg msg = {
66		.addr = state->config->demod_address,
67		.flags = 0,
68		.buf = buf,
69		.len = 2
70	};
71
72	ret = i2c_transfer(state->i2c, &msg, 1);
73
74	if (ret != 1)
75		dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
76			"ret == %i)\n", __func__, reg, data, ret);
77
78	return (ret != 1) ? -EREMOTEIO : 0;
79}
80
81static int stv0288_write(struct dvb_frontend *fe, u8 *buf, int len)
82{
83	struct stv0288_state *state = fe->demodulator_priv;
84
85	if (len != 2)
86		return -EINVAL;
87
88	return stv0288_writeregI(state, buf[0], buf[1]);
89}
90
91static u8 stv0288_readreg(struct stv0288_state *state, u8 reg)
92{
93	int ret;
94	u8 b0[] = { reg };
95	u8 b1[] = { 0 };
96	struct i2c_msg msg[] = {
97		{
98			.addr = state->config->demod_address,
99			.flags = 0,
100			.buf = b0,
101			.len = 1
102		}, {
103			.addr = state->config->demod_address,
104			.flags = I2C_M_RD,
105			.buf = b1,
106			.len = 1
107		}
108	};
109
110	ret = i2c_transfer(state->i2c, msg, 2);
111
112	if (ret != 2)
113		dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
114				__func__, reg, ret);
115
116	return b1[0];
117}
118
119static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate)
120{
121	struct stv0288_state *state = fe->demodulator_priv;
122	unsigned int temp;
123	unsigned char b[3];
124
125	if ((srate < 1000000) || (srate > 45000000))
126		return -EINVAL;
127
128	temp = (unsigned int)srate / 1000;
129
130		temp = temp * 32768;
131		temp = temp / 25;
132		temp = temp / 125;
133		b[0] = (unsigned char)((temp >> 12) & 0xff);
134		b[1] = (unsigned char)((temp >> 4) & 0xff);
135		b[2] = (unsigned char)((temp << 4) & 0xf0);
136		stv0288_writeregI(state, 0x28, 0x80); /* SFRH */
137		stv0288_writeregI(state, 0x29, 0); /* SFRM */
138		stv0288_writeregI(state, 0x2a, 0); /* SFRL */
139
140		stv0288_writeregI(state, 0x28, b[0]);
141		stv0288_writeregI(state, 0x29, b[1]);
142		stv0288_writeregI(state, 0x2a, b[2]);
143		dprintk("stv0288: stv0288_set_symbolrate\n");
144
145	return 0;
146}
147
148static int stv0288_send_diseqc_msg(struct dvb_frontend *fe,
149				    struct dvb_diseqc_master_cmd *m)
150{
151	struct stv0288_state *state = fe->demodulator_priv;
152
153	int i;
154
155	dprintk("%s\n", __func__);
156
157	stv0288_writeregI(state, 0x09, 0);
158	msleep(30);
159	stv0288_writeregI(state, 0x05, 0x16);
160
161	for (i = 0; i < m->msg_len; i++) {
162		if (stv0288_writeregI(state, 0x06, m->msg[i]))
163			return -EREMOTEIO;
164		msleep(12);
165	}
166
167	return 0;
168}
169
170static int stv0288_send_diseqc_burst(struct dvb_frontend *fe,
171						fe_sec_mini_cmd_t burst)
172{
173	struct stv0288_state *state = fe->demodulator_priv;
174
175	dprintk("%s\n", __func__);
176
177	if (stv0288_writeregI(state, 0x05, 0x16))/* burst mode */
178		return -EREMOTEIO;
179
180	if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff))
181		return -EREMOTEIO;
182
183	if (stv0288_writeregI(state, 0x06, 0x12))
184		return -EREMOTEIO;
185
186	return 0;
187}
188
189static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
190{
191	struct stv0288_state *state = fe->demodulator_priv;
192
193	switch (tone) {
194	case SEC_TONE_ON:
195		if (stv0288_writeregI(state, 0x05, 0x10))/* burst mode */
196			return -EREMOTEIO;
197		return stv0288_writeregI(state, 0x06, 0xff);
198
199	case SEC_TONE_OFF:
200		if (stv0288_writeregI(state, 0x05, 0x13))/* burst mode */
201			return -EREMOTEIO;
202		return stv0288_writeregI(state, 0x06, 0x00);
203
204	default:
205		return -EINVAL;
206	}
207}
208
209static u8 stv0288_inittab[] = {
210	0x01, 0x15,
211	0x02, 0x20,
212	0x09, 0x0,
213	0x0a, 0x4,
214	0x0b, 0x0,
215	0x0c, 0x0,
216	0x0d, 0x0,
217	0x0e, 0xd4,
218	0x0f, 0x30,
219	0x11, 0x80,
220	0x12, 0x03,
221	0x13, 0x48,
222	0x14, 0x84,
223	0x15, 0x45,
224	0x16, 0xb7,
225	0x17, 0x9c,
226	0x18, 0x0,
227	0x19, 0xa6,
228	0x1a, 0x88,
229	0x1b, 0x8f,
230	0x1c, 0xf0,
231	0x20, 0x0b,
232	0x21, 0x54,
233	0x22, 0x0,
234	0x23, 0x0,
235	0x2b, 0xff,
236	0x2c, 0xf7,
237	0x30, 0x0,
238	0x31, 0x1e,
239	0x32, 0x14,
240	0x33, 0x0f,
241	0x34, 0x09,
242	0x35, 0x0c,
243	0x36, 0x05,
244	0x37, 0x2f,
245	0x38, 0x16,
246	0x39, 0xbe,
247	0x3a, 0x0,
248	0x3b, 0x13,
249	0x3c, 0x11,
250	0x3d, 0x30,
251	0x40, 0x63,
252	0x41, 0x04,
253	0x42, 0x60,
254	0x43, 0x00,
255	0x44, 0x00,
256	0x45, 0x00,
257	0x46, 0x00,
258	0x47, 0x00,
259	0x4a, 0x00,
260	0x50, 0x10,
261	0x51, 0x38,
262	0x52, 0x21,
263	0x58, 0x54,
264	0x59, 0x86,
265	0x5a, 0x0,
266	0x5b, 0x9b,
267	0x5c, 0x08,
268	0x5d, 0x7f,
269	0x5e, 0x0,
270	0x5f, 0xff,
271	0x70, 0x0,
272	0x71, 0x0,
273	0x72, 0x0,
274	0x74, 0x0,
275	0x75, 0x0,
276	0x76, 0x0,
277	0x81, 0x0,
278	0x82, 0x3f,
279	0x83, 0x3f,
280	0x84, 0x0,
281	0x85, 0x0,
282	0x88, 0x0,
283	0x89, 0x0,
284	0x8a, 0x0,
285	0x8b, 0x0,
286	0x8c, 0x0,
287	0x90, 0x0,
288	0x91, 0x0,
289	0x92, 0x0,
290	0x93, 0x0,
291	0x94, 0x1c,
292	0x97, 0x0,
293	0xa0, 0x48,
294	0xa1, 0x0,
295	0xb0, 0xb8,
296	0xb1, 0x3a,
297	0xb2, 0x10,
298	0xb3, 0x82,
299	0xb4, 0x80,
300	0xb5, 0x82,
301	0xb6, 0x82,
302	0xb7, 0x82,
303	0xb8, 0x20,
304	0xb9, 0x0,
305	0xf0, 0x0,
306	0xf1, 0x0,
307	0xf2, 0xc0,
308	0x51, 0x36,
309	0x52, 0x09,
310	0x53, 0x94,
311	0x54, 0x62,
312	0x55, 0x29,
313	0x56, 0x64,
314	0x57, 0x2b,
315	0xff, 0xff,
316};
317
318static int stv0288_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
319{
320	dprintk("%s: %s\n", __func__,
321		volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
322		volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
323
324	return 0;
325}
326
327static int stv0288_init(struct dvb_frontend *fe)
328{
329	struct stv0288_state *state = fe->demodulator_priv;
330	int i;
331	u8 reg;
332	u8 val;
333
334	dprintk("stv0288: init chip\n");
335	stv0288_writeregI(state, 0x41, 0x04);
336	msleep(50);
337
338	/* we have default inittab */
339	if (state->config->inittab == NULL) {
340		for (i = 0; !(stv0288_inittab[i] == 0xff &&
341				stv0288_inittab[i + 1] == 0xff); i += 2)
342			stv0288_writeregI(state, stv0288_inittab[i],
343					stv0288_inittab[i + 1]);
344	} else {
345		for (i = 0; ; i += 2)  {
346			reg = state->config->inittab[i];
347			val = state->config->inittab[i+1];
348			if (reg == 0xff && val == 0xff)
349				break;
350			stv0288_writeregI(state, reg, val);
351		}
352	}
353	return 0;
354}
355
356static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status)
357{
358	struct stv0288_state *state = fe->demodulator_priv;
359
360	u8 sync = stv0288_readreg(state, 0x24);
361	if (sync == 255)
362		sync = 0;
363
364	dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
365
366	*status = 0;
367
368	if ((sync & 0x08) == 0x08) {
369		*status |= FE_HAS_LOCK;
370		dprintk("stv0288 has locked\n");
371	}
372
373	return 0;
374}
375
376static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber)
377{
378	struct stv0288_state *state = fe->demodulator_priv;
379
380	if (state->errmode != STATUS_BER)
381		return 0;
382	*ber = (stv0288_readreg(state, 0x26) << 8) |
383					stv0288_readreg(state, 0x27);
384	dprintk("stv0288_read_ber %d\n", *ber);
385
386	return 0;
387}
388
389
390static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
391{
392	struct stv0288_state *state = fe->demodulator_priv;
393
394	s32 signal =  0xffff - ((stv0288_readreg(state, 0x10) << 8));
395
396
397	signal = signal * 5 / 4;
398	*strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
399	dprintk("stv0288_read_signal_strength %d\n", *strength);
400
401	return 0;
402}
403static int stv0288_sleep(struct dvb_frontend *fe)
404{
405	struct stv0288_state *state = fe->demodulator_priv;
406
407	stv0288_writeregI(state, 0x41, 0x84);
408	state->initialised = 0;
409
410	return 0;
411}
412static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr)
413{
414	struct stv0288_state *state = fe->demodulator_priv;
415
416	s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8)
417			   | stv0288_readreg(state, 0x2e));
418	xsnr = 3 * (xsnr - 0xa100);
419	*snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
420	dprintk("stv0288_read_snr %d\n", *snr);
421
422	return 0;
423}
424
425static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
426{
427	struct stv0288_state *state = fe->demodulator_priv;
428
429	if (state->errmode != STATUS_BER)
430		return 0;
431	*ucblocks = (stv0288_readreg(state, 0x26) << 8) |
432					stv0288_readreg(state, 0x27);
433	dprintk("stv0288_read_ber %d\n", *ucblocks);
434
435	return 0;
436}
437
438static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p)
439{
440	dprintk("%s(..)\n", __func__);
441	return 0;
442}
443
444static int stv0288_get_property(struct dvb_frontend *fe, struct dtv_property *p)
445{
446	dprintk("%s(..)\n", __func__);
447	return 0;
448}
449
450static int stv0288_set_frontend(struct dvb_frontend *fe,
451					struct dvb_frontend_parameters *dfp)
452{
453	struct stv0288_state *state = fe->demodulator_priv;
454	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
455
456	char tm;
457	unsigned char tda[3];
458
459	dprintk("%s : FE_SET_FRONTEND\n", __func__);
460
461	if (c->delivery_system != SYS_DVBS) {
462			dprintk("%s: unsupported delivery "
463				"system selected (%d)\n",
464				__func__, c->delivery_system);
465			return -EOPNOTSUPP;
466	}
467
468	if (state->config->set_ts_params)
469		state->config->set_ts_params(fe, 0);
470
471	/* only frequency & symbol_rate are used for tuner*/
472	dfp->frequency = c->frequency;
473	dfp->u.qpsk.symbol_rate = c->symbol_rate;
474	if (fe->ops.tuner_ops.set_params) {
475		fe->ops.tuner_ops.set_params(fe, dfp);
476		if (fe->ops.i2c_gate_ctrl)
477			fe->ops.i2c_gate_ctrl(fe, 0);
478	}
479
480	udelay(10);
481	stv0288_set_symbolrate(fe, c->symbol_rate);
482	/* Carrier lock control register */
483	stv0288_writeregI(state, 0x15, 0xc5);
484
485	tda[0] = 0x2b; /* CFRM */
486	tda[2] = 0x0; /* CFRL */
487	for (tm = -6; tm < 7;) {
488		/* Viterbi status */
489		if (stv0288_readreg(state, 0x24) & 0x80)
490			break;
491
492		tda[2] += 40;
493		if (tda[2] < 40)
494			tm++;
495		tda[1] = (unsigned char)tm;
496		stv0288_writeregI(state, 0x2b, tda[1]);
497		stv0288_writeregI(state, 0x2c, tda[2]);
498		udelay(30);
499	}
500
501	state->tuner_frequency = c->frequency;
502	state->fec_inner = FEC_AUTO;
503	state->symbol_rate = c->symbol_rate;
504
505	return 0;
506}
507
508static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
509{
510	struct stv0288_state *state = fe->demodulator_priv;
511
512	if (enable)
513		stv0288_writeregI(state, 0x01, 0xb5);
514	else
515		stv0288_writeregI(state, 0x01, 0x35);
516
517	udelay(1);
518
519	return 0;
520}
521
522static void stv0288_release(struct dvb_frontend *fe)
523{
524	struct stv0288_state *state = fe->demodulator_priv;
525	kfree(state);
526}
527
528static struct dvb_frontend_ops stv0288_ops = {
529
530	.info = {
531		.name			= "ST STV0288 DVB-S",
532		.type			= FE_QPSK,
533		.frequency_min		= 950000,
534		.frequency_max		= 2150000,
535		.frequency_stepsize	= 1000,	 /* kHz for QPSK frontends */
536		.frequency_tolerance	= 0,
537		.symbol_rate_min	= 1000000,
538		.symbol_rate_max	= 45000000,
539		.symbol_rate_tolerance	= 500,	/* ppm */
540		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
541		      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
542		      FE_CAN_QPSK |
543		      FE_CAN_FEC_AUTO
544	},
545
546	.release = stv0288_release,
547	.init = stv0288_init,
548	.sleep = stv0288_sleep,
549	.write = stv0288_write,
550	.i2c_gate_ctrl = stv0288_i2c_gate_ctrl,
551	.read_status = stv0288_read_status,
552	.read_ber = stv0288_read_ber,
553	.read_signal_strength = stv0288_read_signal_strength,
554	.read_snr = stv0288_read_snr,
555	.read_ucblocks = stv0288_read_ucblocks,
556	.diseqc_send_master_cmd = stv0288_send_diseqc_msg,
557	.diseqc_send_burst = stv0288_send_diseqc_burst,
558	.set_tone = stv0288_set_tone,
559	.set_voltage = stv0288_set_voltage,
560
561	.set_property = stv0288_set_property,
562	.get_property = stv0288_get_property,
563	.set_frontend = stv0288_set_frontend,
564};
565
566struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
567				    struct i2c_adapter *i2c)
568{
569	struct stv0288_state *state = NULL;
570	int id;
571
572	/* allocate memory for the internal state */
573	state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
574	if (state == NULL)
575		goto error;
576
577	/* setup the state */
578	state->config = config;
579	state->i2c = i2c;
580	state->initialised = 0;
581	state->tuner_frequency = 0;
582	state->symbol_rate = 0;
583	state->fec_inner = 0;
584	state->errmode = STATUS_BER;
585
586	stv0288_writeregI(state, 0x41, 0x04);
587	msleep(200);
588	id = stv0288_readreg(state, 0x00);
589	dprintk("stv0288 id %x\n", id);
590
591	/* register 0x00 contains 0x11 for STV0288  */
592	if (id != 0x11)
593		goto error;
594
595	/* create dvb_frontend */
596	memcpy(&state->frontend.ops, &stv0288_ops,
597			sizeof(struct dvb_frontend_ops));
598	state->frontend.demodulator_priv = state;
599	return &state->frontend;
600
601error:
602	kfree(state);
603
604	return NULL;
605}
606EXPORT_SYMBOL(stv0288_attach);
607
608module_param(debug_legacy_dish_switch, int, 0444);
609MODULE_PARM_DESC(debug_legacy_dish_switch,
610		"Enable timing analysis for Dish Network legacy switches");
611
612module_param(debug, int, 0644);
613MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
614
615MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
616MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
617MODULE_LICENSE("GPL");
618