• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
37 struct 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 
52 static int debug;
53 static 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 
stv0288_writeregI(struct stv0288_state * state,u8 reg,u8 data)61 static 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 
stv0288_write(struct dvb_frontend * fe,u8 * buf,int len)81 static 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 
stv0288_readreg(struct stv0288_state * state,u8 reg)91 static 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 
stv0288_set_symbolrate(struct dvb_frontend * fe,u32 srate)119 static 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 
stv0288_send_diseqc_msg(struct dvb_frontend * fe,struct dvb_diseqc_master_cmd * m)148 static 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 
stv0288_send_diseqc_burst(struct dvb_frontend * fe,fe_sec_mini_cmd_t burst)170 static 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 
stv0288_set_tone(struct dvb_frontend * fe,fe_sec_tone_mode_t tone)189 static 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 
209 static 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 
stv0288_set_voltage(struct dvb_frontend * fe,fe_sec_voltage_t volt)318 static 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 
stv0288_init(struct dvb_frontend * fe)327 static 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 
stv0288_read_status(struct dvb_frontend * fe,fe_status_t * status)356 static 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 
stv0288_read_ber(struct dvb_frontend * fe,u32 * ber)376 static 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 
stv0288_read_signal_strength(struct dvb_frontend * fe,u16 * strength)390 static 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 }
stv0288_sleep(struct dvb_frontend * fe)403 static 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 }
stv0288_read_snr(struct dvb_frontend * fe,u16 * snr)412 static 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 
stv0288_read_ucblocks(struct dvb_frontend * fe,u32 * ucblocks)425 static 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 
stv0288_set_property(struct dvb_frontend * fe,struct dtv_property * p)438 static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p)
439 {
440 	dprintk("%s(..)\n", __func__);
441 	return 0;
442 }
443 
stv0288_get_property(struct dvb_frontend * fe,struct dtv_property * p)444 static int stv0288_get_property(struct dvb_frontend *fe, struct dtv_property *p)
445 {
446 	dprintk("%s(..)\n", __func__);
447 	return 0;
448 }
449 
stv0288_set_frontend(struct dvb_frontend * fe,struct dvb_frontend_parameters * dfp)450 static 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 
stv0288_i2c_gate_ctrl(struct dvb_frontend * fe,int enable)508 static 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 
stv0288_release(struct dvb_frontend * fe)522 static void stv0288_release(struct dvb_frontend *fe)
523 {
524 	struct stv0288_state *state = fe->demodulator_priv;
525 	kfree(state);
526 }
527 
528 static 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 
stv0288_attach(const struct stv0288_config * config,struct i2c_adapter * i2c)566 struct 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 = kmalloc(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 
601 error:
602 	kfree(state);
603 
604 	return NULL;
605 }
606 EXPORT_SYMBOL(stv0288_attach);
607 
608 module_param(debug_legacy_dish_switch, int, 0444);
609 MODULE_PARM_DESC(debug_legacy_dish_switch,
610 		"Enable timing analysis for Dish Network legacy switches");
611 
612 module_param(debug, int, 0644);
613 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
614 
615 MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
616 MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
617 MODULE_LICENSE("GPL");
618 
619