• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 	Driver for ST STV0288 demodulator
4 	Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
5 		for Reel Multimedia
6 	Copyright (C) 2008 TurboSight.com, Bob Liu <bob@turbosight.com>
7 	Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
8 		Removed stb6000 specific tuner code and revised some
9 		procedures.
10 	2010-09-01 Josef Pavlik <josef@pavlik.it>
11 		Fixed diseqc_msg, diseqc_burst and set_tone problems
12 
13 
14 */
15 
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/string.h>
20 #include <linux/slab.h>
21 #include <linux/jiffies.h>
22 #include <asm/div64.h>
23 
24 #include <media/dvb_frontend.h>
25 #include "stv0288.h"
26 
27 struct stv0288_state {
28 	struct i2c_adapter *i2c;
29 	const struct stv0288_config *config;
30 	struct dvb_frontend frontend;
31 
32 	u8 initialised:1;
33 	u32 tuner_frequency;
34 	u32 symbol_rate;
35 	enum fe_code_rate fec_inner;
36 	int errmode;
37 };
38 
39 #define STATUS_BER 0
40 #define STATUS_UCBLOCKS 1
41 
42 static int debug;
43 static int debug_legacy_dish_switch;
44 #define dprintk(args...) \
45 	do { \
46 		if (debug) \
47 			printk(KERN_DEBUG "stv0288: " args); \
48 	} while (0)
49 
50 
stv0288_writeregI(struct stv0288_state * state,u8 reg,u8 data)51 static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data)
52 {
53 	int ret;
54 	u8 buf[] = { reg, data };
55 	struct i2c_msg msg = {
56 		.addr = state->config->demod_address,
57 		.flags = 0,
58 		.buf = buf,
59 		.len = 2
60 	};
61 
62 	ret = i2c_transfer(state->i2c, &msg, 1);
63 
64 	if (ret != 1)
65 		dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
66 			__func__, reg, data, ret);
67 
68 	return (ret != 1) ? -EREMOTEIO : 0;
69 }
70 
stv0288_write(struct dvb_frontend * fe,const u8 buf[],int len)71 static int stv0288_write(struct dvb_frontend *fe, const u8 buf[], int len)
72 {
73 	struct stv0288_state *state = fe->demodulator_priv;
74 
75 	if (len != 2)
76 		return -EINVAL;
77 
78 	return stv0288_writeregI(state, buf[0], buf[1]);
79 }
80 
stv0288_readreg(struct stv0288_state * state,u8 reg)81 static u8 stv0288_readreg(struct stv0288_state *state, u8 reg)
82 {
83 	int ret;
84 	u8 b0[] = { reg };
85 	u8 b1[] = { 0 };
86 	struct i2c_msg msg[] = {
87 		{
88 			.addr = state->config->demod_address,
89 			.flags = 0,
90 			.buf = b0,
91 			.len = 1
92 		}, {
93 			.addr = state->config->demod_address,
94 			.flags = I2C_M_RD,
95 			.buf = b1,
96 			.len = 1
97 		}
98 	};
99 
100 	ret = i2c_transfer(state->i2c, msg, 2);
101 
102 	if (ret != 2)
103 		dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
104 				__func__, reg, ret);
105 
106 	return b1[0];
107 }
108 
stv0288_set_symbolrate(struct dvb_frontend * fe,u32 srate)109 static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate)
110 {
111 	struct stv0288_state *state = fe->demodulator_priv;
112 	unsigned int temp;
113 	unsigned char b[3];
114 
115 	if ((srate < 1000000) || (srate > 45000000))
116 		return -EINVAL;
117 
118 	stv0288_writeregI(state, 0x22, 0);
119 	stv0288_writeregI(state, 0x23, 0);
120 	stv0288_writeregI(state, 0x2b, 0xff);
121 	stv0288_writeregI(state, 0x2c, 0xf7);
122 
123 	temp = (unsigned int)srate / 1000;
124 
125 	temp = temp * 32768;
126 	temp = temp / 25;
127 	temp = temp / 125;
128 	b[0] = (unsigned char)((temp >> 12) & 0xff);
129 	b[1] = (unsigned char)((temp >> 4) & 0xff);
130 	b[2] = (unsigned char)((temp << 4) & 0xf0);
131 	stv0288_writeregI(state, 0x28, 0x80); /* SFRH */
132 	stv0288_writeregI(state, 0x29, 0); /* SFRM */
133 	stv0288_writeregI(state, 0x2a, 0); /* SFRL */
134 
135 	stv0288_writeregI(state, 0x28, b[0]);
136 	stv0288_writeregI(state, 0x29, b[1]);
137 	stv0288_writeregI(state, 0x2a, b[2]);
138 	dprintk("stv0288: stv0288_set_symbolrate\n");
139 
140 	return 0;
141 }
142 
stv0288_send_diseqc_msg(struct dvb_frontend * fe,struct dvb_diseqc_master_cmd * m)143 static int stv0288_send_diseqc_msg(struct dvb_frontend *fe,
144 				    struct dvb_diseqc_master_cmd *m)
145 {
146 	struct stv0288_state *state = fe->demodulator_priv;
147 
148 	int i;
149 
150 	dprintk("%s\n", __func__);
151 
152 	stv0288_writeregI(state, 0x09, 0);
153 	msleep(30);
154 	stv0288_writeregI(state, 0x05, 0x12);/* modulated mode, single shot */
155 
156 	for (i = 0; i < m->msg_len; i++) {
157 		if (stv0288_writeregI(state, 0x06, m->msg[i]))
158 			return -EREMOTEIO;
159 	}
160 	msleep(m->msg_len*12);
161 	return 0;
162 }
163 
stv0288_send_diseqc_burst(struct dvb_frontend * fe,enum fe_sec_mini_cmd burst)164 static int stv0288_send_diseqc_burst(struct dvb_frontend *fe,
165 				     enum fe_sec_mini_cmd burst)
166 {
167 	struct stv0288_state *state = fe->demodulator_priv;
168 
169 	dprintk("%s\n", __func__);
170 
171 	if (stv0288_writeregI(state, 0x05, 0x03))/* burst mode, single shot */
172 		return -EREMOTEIO;
173 
174 	if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff))
175 		return -EREMOTEIO;
176 
177 	msleep(15);
178 	if (stv0288_writeregI(state, 0x05, 0x12))
179 		return -EREMOTEIO;
180 
181 	return 0;
182 }
183 
stv0288_set_tone(struct dvb_frontend * fe,enum fe_sec_tone_mode tone)184 static int stv0288_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
185 {
186 	struct stv0288_state *state = fe->demodulator_priv;
187 
188 	switch (tone) {
189 	case SEC_TONE_ON:
190 		if (stv0288_writeregI(state, 0x05, 0x10))/* cont carrier */
191 			return -EREMOTEIO;
192 	break;
193 
194 	case SEC_TONE_OFF:
195 		if (stv0288_writeregI(state, 0x05, 0x12))/* burst mode off*/
196 			return -EREMOTEIO;
197 	break;
198 
199 	default:
200 		return -EINVAL;
201 	}
202 	return 0;
203 }
204 
205 static u8 stv0288_inittab[] = {
206 	0x01, 0x15,
207 	0x02, 0x20,
208 	0x09, 0x0,
209 	0x0a, 0x4,
210 	0x0b, 0x0,
211 	0x0c, 0x0,
212 	0x0d, 0x0,
213 	0x0e, 0xd4,
214 	0x0f, 0x30,
215 	0x11, 0x80,
216 	0x12, 0x03,
217 	0x13, 0x48,
218 	0x14, 0x84,
219 	0x15, 0x45,
220 	0x16, 0xb7,
221 	0x17, 0x9c,
222 	0x18, 0x0,
223 	0x19, 0xa6,
224 	0x1a, 0x88,
225 	0x1b, 0x8f,
226 	0x1c, 0xf0,
227 	0x20, 0x0b,
228 	0x21, 0x54,
229 	0x22, 0x0,
230 	0x23, 0x0,
231 	0x2b, 0xff,
232 	0x2c, 0xf7,
233 	0x30, 0x0,
234 	0x31, 0x1e,
235 	0x32, 0x14,
236 	0x33, 0x0f,
237 	0x34, 0x09,
238 	0x35, 0x0c,
239 	0x36, 0x05,
240 	0x37, 0x2f,
241 	0x38, 0x16,
242 	0x39, 0xbe,
243 	0x3a, 0x0,
244 	0x3b, 0x13,
245 	0x3c, 0x11,
246 	0x3d, 0x30,
247 	0x40, 0x63,
248 	0x41, 0x04,
249 	0x42, 0x20,
250 	0x43, 0x00,
251 	0x44, 0x00,
252 	0x45, 0x00,
253 	0x46, 0x00,
254 	0x47, 0x00,
255 	0x4a, 0x00,
256 	0x50, 0x10,
257 	0x51, 0x38,
258 	0x52, 0x21,
259 	0x58, 0x54,
260 	0x59, 0x86,
261 	0x5a, 0x0,
262 	0x5b, 0x9b,
263 	0x5c, 0x08,
264 	0x5d, 0x7f,
265 	0x5e, 0x0,
266 	0x5f, 0xff,
267 	0x70, 0x0,
268 	0x71, 0x0,
269 	0x72, 0x0,
270 	0x74, 0x0,
271 	0x75, 0x0,
272 	0x76, 0x0,
273 	0x81, 0x0,
274 	0x82, 0x3f,
275 	0x83, 0x3f,
276 	0x84, 0x0,
277 	0x85, 0x0,
278 	0x88, 0x0,
279 	0x89, 0x0,
280 	0x8a, 0x0,
281 	0x8b, 0x0,
282 	0x8c, 0x0,
283 	0x90, 0x0,
284 	0x91, 0x0,
285 	0x92, 0x0,
286 	0x93, 0x0,
287 	0x94, 0x1c,
288 	0x97, 0x0,
289 	0xa0, 0x48,
290 	0xa1, 0x0,
291 	0xb0, 0xb8,
292 	0xb1, 0x3a,
293 	0xb2, 0x10,
294 	0xb3, 0x82,
295 	0xb4, 0x80,
296 	0xb5, 0x82,
297 	0xb6, 0x82,
298 	0xb7, 0x82,
299 	0xb8, 0x20,
300 	0xb9, 0x0,
301 	0xf0, 0x0,
302 	0xf1, 0x0,
303 	0xf2, 0xc0,
304 	0x51, 0x36,
305 	0x52, 0x09,
306 	0x53, 0x94,
307 	0x54, 0x62,
308 	0x55, 0x29,
309 	0x56, 0x64,
310 	0x57, 0x2b,
311 	0xff, 0xff,
312 };
313 
stv0288_set_voltage(struct dvb_frontend * fe,enum fe_sec_voltage volt)314 static int stv0288_set_voltage(struct dvb_frontend *fe,
315 			       enum fe_sec_voltage volt)
316 {
317 	dprintk("%s: %s\n", __func__,
318 		volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
319 		volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
320 
321 	return 0;
322 }
323 
stv0288_init(struct dvb_frontend * fe)324 static int stv0288_init(struct dvb_frontend *fe)
325 {
326 	struct stv0288_state *state = fe->demodulator_priv;
327 	int i;
328 	u8 reg;
329 	u8 val;
330 
331 	dprintk("stv0288: init chip\n");
332 	stv0288_writeregI(state, 0x41, 0x04);
333 	msleep(50);
334 
335 	/* we have default inittab */
336 	if (state->config->inittab == NULL) {
337 		for (i = 0; !(stv0288_inittab[i] == 0xff &&
338 				stv0288_inittab[i + 1] == 0xff); i += 2)
339 			stv0288_writeregI(state, stv0288_inittab[i],
340 					stv0288_inittab[i + 1]);
341 	} else {
342 		for (i = 0; ; i += 2)  {
343 			reg = state->config->inittab[i];
344 			val = state->config->inittab[i+1];
345 			if (reg == 0xff && val == 0xff)
346 				break;
347 			stv0288_writeregI(state, reg, val);
348 		}
349 	}
350 	return 0;
351 }
352 
stv0288_read_status(struct dvb_frontend * fe,enum fe_status * status)353 static int stv0288_read_status(struct dvb_frontend *fe, enum fe_status *status)
354 {
355 	struct stv0288_state *state = fe->demodulator_priv;
356 
357 	u8 sync = stv0288_readreg(state, 0x24);
358 	if (sync == 255)
359 		sync = 0;
360 
361 	dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
362 
363 	*status = 0;
364 	if (sync & 0x80)
365 		*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
366 	if (sync & 0x10)
367 		*status |= FE_HAS_VITERBI;
368 	if (sync & 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_frontend(struct dvb_frontend * fe)438 static int stv0288_set_frontend(struct dvb_frontend *fe)
439 {
440 	struct stv0288_state *state = fe->demodulator_priv;
441 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
442 
443 	char tm;
444 	unsigned char tda[3];
445 	u8 reg, time_out = 0;
446 
447 	dprintk("%s : FE_SET_FRONTEND\n", __func__);
448 
449 	if (c->delivery_system != SYS_DVBS) {
450 		dprintk("%s: unsupported delivery system selected (%d)\n",
451 			__func__, c->delivery_system);
452 		return -EOPNOTSUPP;
453 	}
454 
455 	if (state->config->set_ts_params)
456 		state->config->set_ts_params(fe, 0);
457 
458 	/* only frequency & symbol_rate are used for tuner*/
459 	if (fe->ops.tuner_ops.set_params) {
460 		fe->ops.tuner_ops.set_params(fe);
461 		if (fe->ops.i2c_gate_ctrl)
462 			fe->ops.i2c_gate_ctrl(fe, 0);
463 	}
464 
465 	udelay(10);
466 	stv0288_set_symbolrate(fe, c->symbol_rate);
467 	/* Carrier lock control register */
468 	stv0288_writeregI(state, 0x15, 0xc5);
469 
470 	tda[2] = 0x0; /* CFRL */
471 	for (tm = -9; tm < 7;) {
472 		/* Viterbi status */
473 		reg = stv0288_readreg(state, 0x24);
474 		if (reg & 0x8)
475 				break;
476 		if (reg & 0x80) {
477 			time_out++;
478 			if (time_out > 10)
479 				break;
480 			tda[2] += 40;
481 			if (tda[2] < 40)
482 				tm++;
483 		} else {
484 			tm++;
485 			tda[2] = 0;
486 			time_out = 0;
487 		}
488 		tda[1] = (unsigned char)tm;
489 		stv0288_writeregI(state, 0x2b, tda[1]);
490 		stv0288_writeregI(state, 0x2c, tda[2]);
491 		msleep(30);
492 	}
493 	state->tuner_frequency = c->frequency;
494 	state->fec_inner = FEC_AUTO;
495 	state->symbol_rate = c->symbol_rate;
496 
497 	return 0;
498 }
499 
stv0288_i2c_gate_ctrl(struct dvb_frontend * fe,int enable)500 static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
501 {
502 	struct stv0288_state *state = fe->demodulator_priv;
503 
504 	if (enable)
505 		stv0288_writeregI(state, 0x01, 0xb5);
506 	else
507 		stv0288_writeregI(state, 0x01, 0x35);
508 
509 	udelay(1);
510 
511 	return 0;
512 }
513 
stv0288_release(struct dvb_frontend * fe)514 static void stv0288_release(struct dvb_frontend *fe)
515 {
516 	struct stv0288_state *state = fe->demodulator_priv;
517 	kfree(state);
518 }
519 
520 static const struct dvb_frontend_ops stv0288_ops = {
521 	.delsys = { SYS_DVBS },
522 	.info = {
523 		.name			= "ST STV0288 DVB-S",
524 		.frequency_min_hz	=  950 * MHz,
525 		.frequency_max_hz	= 2150 * MHz,
526 		.frequency_stepsize_hz	=    1 * MHz,
527 		.symbol_rate_min	= 1000000,
528 		.symbol_rate_max	= 45000000,
529 		.symbol_rate_tolerance	= 500,	/* ppm */
530 		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
531 		      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
532 		      FE_CAN_QPSK |
533 		      FE_CAN_FEC_AUTO
534 	},
535 
536 	.release = stv0288_release,
537 	.init = stv0288_init,
538 	.sleep = stv0288_sleep,
539 	.write = stv0288_write,
540 	.i2c_gate_ctrl = stv0288_i2c_gate_ctrl,
541 	.read_status = stv0288_read_status,
542 	.read_ber = stv0288_read_ber,
543 	.read_signal_strength = stv0288_read_signal_strength,
544 	.read_snr = stv0288_read_snr,
545 	.read_ucblocks = stv0288_read_ucblocks,
546 	.diseqc_send_master_cmd = stv0288_send_diseqc_msg,
547 	.diseqc_send_burst = stv0288_send_diseqc_burst,
548 	.set_tone = stv0288_set_tone,
549 	.set_voltage = stv0288_set_voltage,
550 
551 	.set_frontend = stv0288_set_frontend,
552 };
553 
stv0288_attach(const struct stv0288_config * config,struct i2c_adapter * i2c)554 struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
555 				    struct i2c_adapter *i2c)
556 {
557 	struct stv0288_state *state = NULL;
558 	int id;
559 
560 	/* allocate memory for the internal state */
561 	state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
562 	if (state == NULL)
563 		goto error;
564 
565 	/* setup the state */
566 	state->config = config;
567 	state->i2c = i2c;
568 	state->initialised = 0;
569 	state->tuner_frequency = 0;
570 	state->symbol_rate = 0;
571 	state->fec_inner = 0;
572 	state->errmode = STATUS_BER;
573 
574 	stv0288_writeregI(state, 0x41, 0x04);
575 	msleep(200);
576 	id = stv0288_readreg(state, 0x00);
577 	dprintk("stv0288 id %x\n", id);
578 
579 	/* register 0x00 contains 0x11 for STV0288  */
580 	if (id != 0x11)
581 		goto error;
582 
583 	/* create dvb_frontend */
584 	memcpy(&state->frontend.ops, &stv0288_ops,
585 			sizeof(struct dvb_frontend_ops));
586 	state->frontend.demodulator_priv = state;
587 	return &state->frontend;
588 
589 error:
590 	kfree(state);
591 
592 	return NULL;
593 }
594 EXPORT_SYMBOL(stv0288_attach);
595 
596 module_param(debug_legacy_dish_switch, int, 0444);
597 MODULE_PARM_DESC(debug_legacy_dish_switch,
598 		"Enable timing analysis for Dish Network legacy switches");
599 
600 module_param(debug, int, 0644);
601 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
602 
603 MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
604 MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
605 MODULE_LICENSE("GPL");
606 
607