• 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 	u8 tda[3], reg, time_out = 0;
444 	s8 tm;
445 
446 	dprintk("%s : FE_SET_FRONTEND\n", __func__);
447 
448 	if (c->delivery_system != SYS_DVBS) {
449 		dprintk("%s: unsupported delivery system selected (%d)\n",
450 			__func__, c->delivery_system);
451 		return -EOPNOTSUPP;
452 	}
453 
454 	if (state->config->set_ts_params)
455 		state->config->set_ts_params(fe, 0);
456 
457 	/* only frequency & symbol_rate are used for tuner*/
458 	if (fe->ops.tuner_ops.set_params) {
459 		fe->ops.tuner_ops.set_params(fe);
460 		if (fe->ops.i2c_gate_ctrl)
461 			fe->ops.i2c_gate_ctrl(fe, 0);
462 	}
463 
464 	udelay(10);
465 	stv0288_set_symbolrate(fe, c->symbol_rate);
466 	/* Carrier lock control register */
467 	stv0288_writeregI(state, 0x15, 0xc5);
468 
469 	tda[2] = 0x0; /* CFRL */
470 	for (tm = -9; tm < 7;) {
471 		/* Viterbi status */
472 		reg = stv0288_readreg(state, 0x24);
473 		if (reg & 0x8)
474 				break;
475 		if (reg & 0x80) {
476 			time_out++;
477 			if (time_out > 10)
478 				break;
479 			tda[2] += 40;
480 			if (tda[2] < 40)
481 				tm++;
482 		} else {
483 			tm++;
484 			tda[2] = 0;
485 			time_out = 0;
486 		}
487 		tda[1] = (unsigned char)tm;
488 		stv0288_writeregI(state, 0x2b, tda[1]);
489 		stv0288_writeregI(state, 0x2c, tda[2]);
490 		msleep(30);
491 	}
492 	state->tuner_frequency = c->frequency;
493 	state->fec_inner = FEC_AUTO;
494 	state->symbol_rate = c->symbol_rate;
495 
496 	return 0;
497 }
498 
stv0288_i2c_gate_ctrl(struct dvb_frontend * fe,int enable)499 static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
500 {
501 	struct stv0288_state *state = fe->demodulator_priv;
502 
503 	if (enable)
504 		stv0288_writeregI(state, 0x01, 0xb5);
505 	else
506 		stv0288_writeregI(state, 0x01, 0x35);
507 
508 	udelay(1);
509 
510 	return 0;
511 }
512 
stv0288_release(struct dvb_frontend * fe)513 static void stv0288_release(struct dvb_frontend *fe)
514 {
515 	struct stv0288_state *state = fe->demodulator_priv;
516 	kfree(state);
517 }
518 
519 static const struct dvb_frontend_ops stv0288_ops = {
520 	.delsys = { SYS_DVBS },
521 	.info = {
522 		.name			= "ST STV0288 DVB-S",
523 		.frequency_min_hz	=  950 * MHz,
524 		.frequency_max_hz	= 2150 * MHz,
525 		.frequency_stepsize_hz	=    1 * MHz,
526 		.symbol_rate_min	= 1000000,
527 		.symbol_rate_max	= 45000000,
528 		.symbol_rate_tolerance	= 500,	/* ppm */
529 		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
530 		      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
531 		      FE_CAN_QPSK |
532 		      FE_CAN_FEC_AUTO
533 	},
534 
535 	.release = stv0288_release,
536 	.init = stv0288_init,
537 	.sleep = stv0288_sleep,
538 	.write = stv0288_write,
539 	.i2c_gate_ctrl = stv0288_i2c_gate_ctrl,
540 	.read_status = stv0288_read_status,
541 	.read_ber = stv0288_read_ber,
542 	.read_signal_strength = stv0288_read_signal_strength,
543 	.read_snr = stv0288_read_snr,
544 	.read_ucblocks = stv0288_read_ucblocks,
545 	.diseqc_send_master_cmd = stv0288_send_diseqc_msg,
546 	.diseqc_send_burst = stv0288_send_diseqc_burst,
547 	.set_tone = stv0288_set_tone,
548 	.set_voltage = stv0288_set_voltage,
549 
550 	.set_frontend = stv0288_set_frontend,
551 };
552 
stv0288_attach(const struct stv0288_config * config,struct i2c_adapter * i2c)553 struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
554 				    struct i2c_adapter *i2c)
555 {
556 	struct stv0288_state *state = NULL;
557 	int id;
558 
559 	/* allocate memory for the internal state */
560 	state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
561 	if (state == NULL)
562 		goto error;
563 
564 	/* setup the state */
565 	state->config = config;
566 	state->i2c = i2c;
567 	state->initialised = 0;
568 	state->tuner_frequency = 0;
569 	state->symbol_rate = 0;
570 	state->fec_inner = 0;
571 	state->errmode = STATUS_BER;
572 
573 	stv0288_writeregI(state, 0x41, 0x04);
574 	msleep(200);
575 	id = stv0288_readreg(state, 0x00);
576 	dprintk("stv0288 id %x\n", id);
577 
578 	/* register 0x00 contains 0x11 for STV0288  */
579 	if (id != 0x11)
580 		goto error;
581 
582 	/* create dvb_frontend */
583 	memcpy(&state->frontend.ops, &stv0288_ops,
584 			sizeof(struct dvb_frontend_ops));
585 	state->frontend.demodulator_priv = state;
586 	return &state->frontend;
587 
588 error:
589 	kfree(state);
590 
591 	return NULL;
592 }
593 EXPORT_SYMBOL(stv0288_attach);
594 
595 module_param(debug_legacy_dish_switch, int, 0444);
596 MODULE_PARM_DESC(debug_legacy_dish_switch,
597 		"Enable timing analysis for Dish Network legacy switches");
598 
599 module_param(debug, int, 0644);
600 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
601 
602 MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
603 MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
604 MODULE_LICENSE("GPL");
605 
606