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,
354			      enum fe_status *fe_status)
355{
356	struct sp8870_state* state = fe->demodulator_priv;
357	int status;
358	int signal;
359
360	*fe_status = 0;
361
362	status = sp8870_readreg (state, 0x0200);
363	if (status < 0)
364		return -EIO;
365
366	signal = sp8870_readreg (state, 0x0303);
367	if (signal < 0)
368		return -EIO;
369
370	if (signal > 0x0F)
371		*fe_status |= FE_HAS_SIGNAL;
372	if (status & 0x08)
373		*fe_status |= FE_HAS_SYNC;
374	if (status & 0x04)
375		*fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI;
376
377	return 0;
378}
379
380static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
381{
382	struct sp8870_state* state = fe->demodulator_priv;
383	int ret;
384	u32 tmp;
385
386	*ber = 0;
387
388	ret = sp8870_readreg(state, 0xC08);
389	if (ret < 0)
390		return -EIO;
391
392	tmp = ret & 0x3F;
393
394	ret = sp8870_readreg(state, 0xC07);
395	if (ret < 0)
396		return -EIO;
397
398	tmp = ret << 6;
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)
463{
464	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
465	struct sp8870_state* state = fe->demodulator_priv;
466
467	/*
468	    The firmware of the sp8870 sometimes locks up after setting frontend parameters.
469	    We try to detect this by checking the data valid signal.
470	    If it is not set after MAXCHECKS we try to recover the lockup by setting
471	    the frontend parameters again.
472	*/
473
474	int err = 0;
475	int valid = 0;
476	int trials = 0;
477	int check_count = 0;
478
479	dprintk("%s: frequency = %i\n", __func__, p->frequency);
480
481	for (trials = 1; trials <= MAXTRIALS; trials++) {
482
483		err = sp8870_set_frontend_parameters(fe);
484		if (err)
485			return err;
486
487		for (check_count = 0; check_count < MAXCHECKS; check_count++) {
488//			valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
489			valid = sp8870_read_data_valid_signal(state);
490			if (valid) {
491				dprintk("%s: delay = %i usec\n",
492					__func__, check_count * 10);
493				break;
494			}
495			udelay(10);
496		}
497		if (valid)
498			break;
499	}
500
501	if (!valid) {
502		printk("%s: firmware crash!!!!!!\n", __func__);
503		return -EIO;
504	}
505
506	if (debug) {
507		if (valid) {
508			if (trials > 1) {
509				printk("%s: firmware lockup!!!\n", __func__);
510				printk("%s: recovered after %i trial(s))\n",  __func__, trials - 1);
511				lockups++;
512			}
513		}
514		switches++;
515		printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups);
516	}
517
518	return 0;
519}
520
521static int sp8870_sleep(struct dvb_frontend* fe)
522{
523	struct sp8870_state* state = fe->demodulator_priv;
524
525	// tristate TS output and disable interface pins
526	return sp8870_writereg(state, 0xC18, 0x000);
527}
528
529static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
530{
531	fesettings->min_delay_ms = 350;
532	fesettings->step_size = 0;
533	fesettings->max_drift = 0;
534	return 0;
535}
536
537static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
538{
539	struct sp8870_state* state = fe->demodulator_priv;
540
541	if (enable) {
542		return sp8870_writereg(state, 0x206, 0x001);
543	} else {
544		return sp8870_writereg(state, 0x206, 0x000);
545	}
546}
547
548static void sp8870_release(struct dvb_frontend* fe)
549{
550	struct sp8870_state* state = fe->demodulator_priv;
551	kfree(state);
552}
553
554static struct dvb_frontend_ops sp8870_ops;
555
556struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
557				   struct i2c_adapter* i2c)
558{
559	struct sp8870_state* state = NULL;
560
561	/* allocate memory for the internal state */
562	state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL);
563	if (state == NULL) goto error;
564
565	/* setup the state */
566	state->config = config;
567	state->i2c = i2c;
568	state->initialised = 0;
569
570	/* check if the demod is there */
571	if (sp8870_readreg(state, 0x0200) < 0) goto error;
572
573	/* create dvb_frontend */
574	memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
575	state->frontend.demodulator_priv = state;
576	return &state->frontend;
577
578error:
579	kfree(state);
580	return NULL;
581}
582
583static struct dvb_frontend_ops sp8870_ops = {
584	.delsys = { SYS_DVBT },
585	.info = {
586		.name			= "Spase SP8870 DVB-T",
587		.frequency_min		= 470000000,
588		.frequency_max		= 860000000,
589		.frequency_stepsize	= 166666,
590		.caps			= FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
591					  FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
592					  FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
593					  FE_CAN_QPSK | FE_CAN_QAM_16 |
594					  FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
595					  FE_CAN_HIERARCHY_AUTO |  FE_CAN_RECOVER
596	},
597
598	.release = sp8870_release,
599
600	.init = sp8870_init,
601	.sleep = sp8870_sleep,
602	.i2c_gate_ctrl = sp8870_i2c_gate_ctrl,
603
604	.set_frontend = sp8870_set_frontend,
605	.get_tune_settings = sp8870_get_tune_settings,
606
607	.read_status = sp8870_read_status,
608	.read_ber = sp8870_read_ber,
609	.read_signal_strength = sp8870_read_signal_strength,
610	.read_ucblocks = sp8870_read_uncorrected_blocks,
611};
612
613module_param(debug, int, 0644);
614MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
615
616MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
617MODULE_AUTHOR("Juergen Peitz");
618MODULE_LICENSE("GPL");
619
620EXPORT_SYMBOL(sp8870_attach);
621