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 dtv_frontend_properties *p, u16 *reg0xc05)
172{
173	int known_parameters = 1;
174
175	*reg0xc05 = 0x000;
176
177	switch (p->modulation) {
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->hierarchy) {
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->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{
250	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
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);
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->bandwidth_hz == 6000000)
281		sp8870_writereg(state, 0x0311, 0x0002);
282	else if (p->bandwidth_hz == 7000000)
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->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	if (tmp >= 0x3FFF0)
399		tmp = ~0;
400
401	*ber = tmp;
402
403	return 0;
404}
405
406static int sp8870_read_signal_strength(struct dvb_frontend* fe,  u16 * signal)
407{
408	struct sp8870_state* state = fe->demodulator_priv;
409	int ret;
410	u16 tmp;
411
412	*signal = 0;
413
414	ret = sp8870_readreg (state, 0x306);
415	if (ret < 0)
416		return -EIO;
417
418	tmp = ret << 8;
419
420	ret = sp8870_readreg (state, 0x303);
421	if (ret < 0)
422		return -EIO;
423
424	tmp |= ret;
425
426	if (tmp)
427		*signal = 0xFFFF - tmp;
428
429	return 0;
430}
431
432static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
433{
434	struct sp8870_state* state = fe->demodulator_priv;
435	int ret;
436
437	*ublocks = 0;
438
439	ret = sp8870_readreg(state, 0xC0C);
440	if (ret < 0)
441		return -EIO;
442
443	if (ret == 0xFFFF)
444		ret = ~0;
445
446	*ublocks = ret;
447
448	return 0;
449}
450
451/* number of trials to recover from lockup */
452#define MAXTRIALS 5
453/* maximum checks for data valid signal */
454#define MAXCHECKS 100
455
456/* only for debugging: counter for detected lockups */
457static int lockups;
458/* only for debugging: counter for channel switches */
459static int switches;
460
461static int sp8870_set_frontend(struct dvb_frontend *fe)
462{
463	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
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		err = sp8870_set_frontend_parameters(fe);
483		if (err)
484			return err;
485
486		for (check_count = 0; check_count < MAXCHECKS; check_count++) {
487//			valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
488			valid = sp8870_read_data_valid_signal(state);
489			if (valid) {
490				dprintk("%s: delay = %i usec\n",
491					__func__, check_count * 10);
492				break;
493			}
494			udelay(10);
495		}
496		if (valid)
497			break;
498	}
499
500	if (!valid) {
501		printk("%s: firmware crash!!!!!!\n", __func__);
502		return -EIO;
503	}
504
505	if (debug) {
506		if (valid) {
507			if (trials > 1) {
508				printk("%s: firmware lockup!!!\n", __func__);
509				printk("%s: recovered after %i trial(s))\n",  __func__, trials - 1);
510				lockups++;
511			}
512		}
513		switches++;
514		printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups);
515	}
516
517	return 0;
518}
519
520static int sp8870_sleep(struct dvb_frontend* fe)
521{
522	struct sp8870_state* state = fe->demodulator_priv;
523
524	// tristate TS output and disable interface pins
525	return sp8870_writereg(state, 0xC18, 0x000);
526}
527
528static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
529{
530	fesettings->min_delay_ms = 350;
531	fesettings->step_size = 0;
532	fesettings->max_drift = 0;
533	return 0;
534}
535
536static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
537{
538	struct sp8870_state* state = fe->demodulator_priv;
539
540	if (enable) {
541		return sp8870_writereg(state, 0x206, 0x001);
542	} else {
543		return sp8870_writereg(state, 0x206, 0x000);
544	}
545}
546
547static void sp8870_release(struct dvb_frontend* fe)
548{
549	struct sp8870_state* state = fe->demodulator_priv;
550	kfree(state);
551}
552
553static struct dvb_frontend_ops sp8870_ops;
554
555struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
556				   struct i2c_adapter* i2c)
557{
558	struct sp8870_state* state = NULL;
559
560	/* allocate memory for the internal state */
561	state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL);
562	if (state == NULL) goto error;
563
564	/* setup the state */
565	state->config = config;
566	state->i2c = i2c;
567	state->initialised = 0;
568
569	/* check if the demod is there */
570	if (sp8870_readreg(state, 0x0200) < 0) goto error;
571
572	/* create dvb_frontend */
573	memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
574	state->frontend.demodulator_priv = state;
575	return &state->frontend;
576
577error:
578	kfree(state);
579	return NULL;
580}
581
582static struct dvb_frontend_ops sp8870_ops = {
583	.delsys = { SYS_DVBT },
584	.info = {
585		.name			= "Spase SP8870 DVB-T",
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