• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/media/dvb/frontends/
1/*
2    Driver for Spase SP8870 demodulator
3
4    Copyright (C) 1999 Juergen Peitz
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22/*
23 * This driver needs external firmware. Please use the command
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to
25 * download/extract it, and then copy it to /usr/lib/hotplug/firmware
26 * or /lib/firmware (depending on configuration of firmware hotplug).
27 */
28#define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw"
29
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/device.h>
33#include <linux/firmware.h>
34#include <linux/delay.h>
35#include <linux/string.h>
36#include <linux/slab.h>
37
38#include "dvb_frontend.h"
39#include "sp8870.h"
40
41
42struct sp8870_state {
43
44	struct i2c_adapter* i2c;
45
46	const struct sp8870_config* config;
47
48	struct dvb_frontend frontend;
49
50	/* demodulator private data */
51	u8 initialised:1;
52};
53
54static int debug;
55#define dprintk(args...) \
56	do { \
57		if (debug) printk(KERN_DEBUG "sp8870: " args); \
58	} while (0)
59
60/* firmware size for sp8870 */
61#define SP8870_FIRMWARE_SIZE 16382
62
63/* starting point for firmware in file 'Sc_main.mc' */
64#define SP8870_FIRMWARE_OFFSET 0x0A
65
66static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
67{
68	u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
69	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 };
70	int err;
71
72	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
73		dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
74		return -EREMOTEIO;
75	}
76
77	return 0;
78}
79
80static int sp8870_readreg (struct sp8870_state* state, u16 reg)
81{
82	int ret;
83	u8 b0 [] = { reg >> 8 , reg & 0xff };
84	u8 b1 [] = { 0, 0 };
85	struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
86			   { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
87
88	ret = i2c_transfer (state->i2c, msg, 2);
89
90	if (ret != 2) {
91		dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
92		return -1;
93	}
94
95	return (b1[0] << 8 | b1[1]);
96}
97
98static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw)
99{
100	struct i2c_msg msg;
101	const char *fw_buf = fw->data;
102	int fw_pos;
103	u8 tx_buf[255];
104	int tx_len;
105	int err = 0;
106
107	dprintk ("%s: ...\n", __func__);
108
109	if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET)
110		return -EINVAL;
111
112	// system controller stop
113	sp8870_writereg(state, 0x0F00, 0x0000);
114
115	// instruction RAM register hiword
116	sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF));
117
118	// instruction RAM MWR
119	sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16));
120
121	// do firmware upload
122	fw_pos = SP8870_FIRMWARE_OFFSET;
123	while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){
124		tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos;
125		// write register 0xCF0A
126		tx_buf[0] = 0xCF;
127		tx_buf[1] = 0x0A;
128		memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len);
129		msg.addr = state->config->demod_address;
130		msg.flags = 0;
131		msg.buf = tx_buf;
132		msg.len = tx_len + 2;
133		if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
134			printk("%s: firmware upload failed!\n", __func__);
135			printk ("%s: i2c error (err == %i)\n", __func__, err);
136			return err;
137		}
138		fw_pos += tx_len;
139	}
140
141	dprintk ("%s: done!\n", __func__);
142	return 0;
143};
144
145static void sp8870_microcontroller_stop (struct sp8870_state* state)
146{
147	sp8870_writereg(state, 0x0F08, 0x000);
148	sp8870_writereg(state, 0x0F09, 0x000);
149
150	// microcontroller STOP
151	sp8870_writereg(state, 0x0F00, 0x000);
152}
153
154static void sp8870_microcontroller_start (struct sp8870_state* state)
155{
156	sp8870_writereg(state, 0x0F08, 0x000);
157	sp8870_writereg(state, 0x0F09, 0x000);
158
159	// microcontroller START
160	sp8870_writereg(state, 0x0F00, 0x001);
161	// not documented but if we don't read 0x0D01 out here
162	// we don't get a correct data valid signal
163	sp8870_readreg(state, 0x0D01);
164}
165
166static int sp8870_read_data_valid_signal(struct sp8870_state* state)
167{
168	return (sp8870_readreg(state, 0x0D02) > 0);
169}
170
171static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05)
172{
173	int known_parameters = 1;
174
175	*reg0xc05 = 0x000;
176
177	switch (p->u.ofdm.constellation) {
178	case QPSK:
179		break;
180	case QAM_16:
181		*reg0xc05 |= (1 << 10);
182		break;
183	case QAM_64:
184		*reg0xc05 |= (2 << 10);
185		break;
186	case QAM_AUTO:
187		known_parameters = 0;
188		break;
189	default:
190		return -EINVAL;
191	};
192
193	switch (p->u.ofdm.hierarchy_information) {
194	case HIERARCHY_NONE:
195		break;
196	case HIERARCHY_1:
197		*reg0xc05 |= (1 << 7);
198		break;
199	case HIERARCHY_2:
200		*reg0xc05 |= (2 << 7);
201		break;
202	case HIERARCHY_4:
203		*reg0xc05 |= (3 << 7);
204		break;
205	case HIERARCHY_AUTO:
206		known_parameters = 0;
207		break;
208	default:
209		return -EINVAL;
210	};
211
212	switch (p->u.ofdm.code_rate_HP) {
213	case FEC_1_2:
214		break;
215	case FEC_2_3:
216		*reg0xc05 |= (1 << 3);
217		break;
218	case FEC_3_4:
219		*reg0xc05 |= (2 << 3);
220		break;
221	case FEC_5_6:
222		*reg0xc05 |= (3 << 3);
223		break;
224	case FEC_7_8:
225		*reg0xc05 |= (4 << 3);
226		break;
227	case FEC_AUTO:
228		known_parameters = 0;
229		break;
230	default:
231		return -EINVAL;
232	};
233
234	if (known_parameters)
235		*reg0xc05 |= (2 << 1);	/* use specified parameters */
236	else
237		*reg0xc05 |= (1 << 1);	/* enable autoprobing */
238
239	return 0;
240}
241
242static int sp8870_wake_up(struct sp8870_state* state)
243{
244	// enable TS output and interface pins
245	return sp8870_writereg(state, 0xC18, 0x00D);
246}
247
248static int sp8870_set_frontend_parameters (struct dvb_frontend* fe,
249					   struct dvb_frontend_parameters *p)
250{
251	struct sp8870_state* state = fe->demodulator_priv;
252	int  err;
253	u16 reg0xc05;
254
255	if ((err = configure_reg0xc05(p, &reg0xc05)))
256		return err;
257
258	// system controller stop
259	sp8870_microcontroller_stop(state);
260
261	// set tuner parameters
262	if (fe->ops.tuner_ops.set_params) {
263		fe->ops.tuner_ops.set_params(fe, p);
264		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
265	}
266
267	// sample rate correction bit [23..17]
268	sp8870_writereg(state, 0x0319, 0x000A);
269
270	// sample rate correction bit [16..0]
271	sp8870_writereg(state, 0x031A, 0x0AAB);
272
273	// integer carrier offset
274	sp8870_writereg(state, 0x0309, 0x0400);
275
276	// fractional carrier offset
277	sp8870_writereg(state, 0x030A, 0x0000);
278
279	// filter for 6/7/8 Mhz channel
280	if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
281		sp8870_writereg(state, 0x0311, 0x0002);
282	else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
283		sp8870_writereg(state, 0x0311, 0x0001);
284	else
285		sp8870_writereg(state, 0x0311, 0x0000);
286
287	// scan order: 2k first = 0x0000, 8k first = 0x0001
288	if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K)
289		sp8870_writereg(state, 0x0338, 0x0000);
290	else
291		sp8870_writereg(state, 0x0338, 0x0001);
292
293	sp8870_writereg(state, 0xc05, reg0xc05);
294
295	// read status reg in order to clear pending irqs
296	sp8870_readreg(state, 0x200);
297
298	// system controller start
299	sp8870_microcontroller_start(state);
300
301	return 0;
302}
303
304static int sp8870_init (struct dvb_frontend* fe)
305{
306	struct sp8870_state* state = fe->demodulator_priv;
307	const struct firmware *fw = NULL;
308
309	sp8870_wake_up(state);
310	if (state->initialised) return 0;
311	state->initialised = 1;
312
313	dprintk ("%s\n", __func__);
314
315
316	/* request the firmware, this will block until someone uploads it */
317	printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
318	if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
319		printk("sp8870: no firmware upload (timeout or file not found?)\n");
320		return -EIO;
321	}
322
323	if (sp8870_firmware_upload(state, fw)) {
324		printk("sp8870: writing firmware to device failed\n");
325		release_firmware(fw);
326		return -EIO;
327	}
328	release_firmware(fw);
329	printk("sp8870: firmware upload complete\n");
330
331	/* enable TS output and interface pins */
332	sp8870_writereg(state, 0xc18, 0x00d);
333
334	// system controller stop
335	sp8870_microcontroller_stop(state);
336
337	// ADC mode
338	sp8870_writereg(state, 0x0301, 0x0003);
339
340	// Reed Solomon parity bytes passed to output
341	sp8870_writereg(state, 0x0C13, 0x0001);
342
343	// MPEG clock is suppressed if no valid data
344	sp8870_writereg(state, 0x0C14, 0x0001);
345
346	/* bit 0x010: enable data valid signal */
347	sp8870_writereg(state, 0x0D00, 0x010);
348	sp8870_writereg(state, 0x0D01, 0x000);
349
350	return 0;
351}
352
353static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status)
354{
355	struct sp8870_state* state = fe->demodulator_priv;
356	int status;
357	int signal;
358
359	*fe_status = 0;
360
361	status = sp8870_readreg (state, 0x0200);
362	if (status < 0)
363		return -EIO;
364
365	signal = sp8870_readreg (state, 0x0303);
366	if (signal < 0)
367		return -EIO;
368
369	if (signal > 0x0F)
370		*fe_status |= FE_HAS_SIGNAL;
371	if (status & 0x08)
372		*fe_status |= FE_HAS_SYNC;
373	if (status & 0x04)
374		*fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI;
375
376	return 0;
377}
378
379static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
380{
381	struct sp8870_state* state = fe->demodulator_priv;
382	int ret;
383	u32 tmp;
384
385	*ber = 0;
386
387	ret = sp8870_readreg(state, 0xC08);
388	if (ret < 0)
389		return -EIO;
390
391	tmp = ret & 0x3F;
392
393	ret = sp8870_readreg(state, 0xC07);
394	if (ret < 0)
395		return -EIO;
396
397	 tmp = ret << 6;
398
399	if (tmp >= 0x3FFF0)
400		tmp = ~0;
401
402	*ber = tmp;
403
404	return 0;
405}
406
407static int sp8870_read_signal_strength(struct dvb_frontend* fe,  u16 * signal)
408{
409	struct sp8870_state* state = fe->demodulator_priv;
410	int ret;
411	u16 tmp;
412
413	*signal = 0;
414
415	ret = sp8870_readreg (state, 0x306);
416	if (ret < 0)
417		return -EIO;
418
419	tmp = ret << 8;
420
421	ret = sp8870_readreg (state, 0x303);
422	if (ret < 0)
423		return -EIO;
424
425	tmp |= ret;
426
427	if (tmp)
428		*signal = 0xFFFF - tmp;
429
430	return 0;
431}
432
433static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
434{
435	struct sp8870_state* state = fe->demodulator_priv;
436	int ret;
437
438	*ublocks = 0;
439
440	ret = sp8870_readreg(state, 0xC0C);
441	if (ret < 0)
442		return -EIO;
443
444	if (ret == 0xFFFF)
445		ret = ~0;
446
447	*ublocks = ret;
448
449	return 0;
450}
451
452/* number of trials to recover from lockup */
453#define MAXTRIALS 5
454/* maximum checks for data valid signal */
455#define MAXCHECKS 100
456
457/* only for debugging: counter for detected lockups */
458static int lockups;
459/* only for debugging: counter for channel switches */
460static int switches;
461
462static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
463{
464	struct sp8870_state* state = fe->demodulator_priv;
465
466	/*
467	    The firmware of the sp8870 sometimes locks up after setting frontend parameters.
468	    We try to detect this by checking the data valid signal.
469	    If it is not set after MAXCHECKS we try to recover the lockup by setting
470	    the frontend parameters again.
471	*/
472
473	int err = 0;
474	int valid = 0;
475	int trials = 0;
476	int check_count = 0;
477
478	dprintk("%s: frequency = %i\n", __func__, p->frequency);
479
480	for (trials = 1; trials <= MAXTRIALS; trials++) {
481
482		if ((err = sp8870_set_frontend_parameters(fe, p)))
483			return err;
484
485		for (check_count = 0; check_count < MAXCHECKS; check_count++) {
486//			valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
487			valid = sp8870_read_data_valid_signal(state);
488			if (valid) {
489				dprintk("%s: delay = %i usec\n",
490					__func__, check_count * 10);
491				break;
492			}
493			udelay(10);
494		}
495		if (valid)
496			break;
497	}
498
499	if (!valid) {
500		printk("%s: firmware crash!!!!!!\n", __func__);
501		return -EIO;
502	}
503
504	if (debug) {
505		if (valid) {
506			if (trials > 1) {
507				printk("%s: firmware lockup!!!\n", __func__);
508				printk("%s: recovered after %i trial(s))\n",  __func__, trials - 1);
509				lockups++;
510			}
511		}
512		switches++;
513		printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups);
514	}
515
516	return 0;
517}
518
519static int sp8870_sleep(struct dvb_frontend* fe)
520{
521	struct sp8870_state* state = fe->demodulator_priv;
522
523	// tristate TS output and disable interface pins
524	return sp8870_writereg(state, 0xC18, 0x000);
525}
526
527static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
528{
529	fesettings->min_delay_ms = 350;
530	fesettings->step_size = 0;
531	fesettings->max_drift = 0;
532	return 0;
533}
534
535static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
536{
537	struct sp8870_state* state = fe->demodulator_priv;
538
539	if (enable) {
540		return sp8870_writereg(state, 0x206, 0x001);
541	} else {
542		return sp8870_writereg(state, 0x206, 0x000);
543	}
544}
545
546static void sp8870_release(struct dvb_frontend* fe)
547{
548	struct sp8870_state* state = fe->demodulator_priv;
549	kfree(state);
550}
551
552static struct dvb_frontend_ops sp8870_ops;
553
554struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
555				   struct i2c_adapter* i2c)
556{
557	struct sp8870_state* state = NULL;
558
559	/* allocate memory for the internal state */
560	state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL);
561	if (state == NULL) goto error;
562
563	/* setup the state */
564	state->config = config;
565	state->i2c = i2c;
566	state->initialised = 0;
567
568	/* check if the demod is there */
569	if (sp8870_readreg(state, 0x0200) < 0) goto error;
570
571	/* create dvb_frontend */
572	memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
573	state->frontend.demodulator_priv = state;
574	return &state->frontend;
575
576error:
577	kfree(state);
578	return NULL;
579}
580
581static struct dvb_frontend_ops sp8870_ops = {
582
583	.info = {
584		.name			= "Spase SP8870 DVB-T",
585		.type			= FE_OFDM,
586		.frequency_min		= 470000000,
587		.frequency_max		= 860000000,
588		.frequency_stepsize	= 166666,
589		.caps			= FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
590					  FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
591					  FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
592					  FE_CAN_QPSK | FE_CAN_QAM_16 |
593					  FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
594					  FE_CAN_HIERARCHY_AUTO |  FE_CAN_RECOVER
595	},
596
597	.release = sp8870_release,
598
599	.init = sp8870_init,
600	.sleep = sp8870_sleep,
601	.i2c_gate_ctrl = sp8870_i2c_gate_ctrl,
602
603	.set_frontend = sp8870_set_frontend,
604	.get_tune_settings = sp8870_get_tune_settings,
605
606	.read_status = sp8870_read_status,
607	.read_ber = sp8870_read_ber,
608	.read_signal_strength = sp8870_read_signal_strength,
609	.read_ucblocks = sp8870_read_uncorrected_blocks,
610};
611
612module_param(debug, int, 0644);
613MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
614
615MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
616MODULE_AUTHOR("Juergen Peitz");
617MODULE_LICENSE("GPL");
618
619EXPORT_SYMBOL(sp8870_attach);
620