2 Driver for Spase SP8870 demodulator
4 Copyright (C) 1999 Juergen Peitz
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.
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
15 GNU General Public License for more details.
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.
24 #include <linux/init.h>
25 #include <linux/module.h>
26 #include <linux/device.h>
27 #include <linux/firmware.h>
28 #include <linux/delay.h>
29 #include <linux/string.h>
30 #include <linux/slab.h>
32 #include "dvb_frontend.h"
38 struct i2c_adapter* i2c;
40 const struct sp8870_config* config;
42 struct dvb_frontend frontend;
44 /* demodulator private data */
49 #define dprintk(args...) \
51 if (debug) printk(KERN_DEBUG "sp8870: " args); \
54 /* firmware size for sp8870 */
55 #define SP8870_FIRMWARE_SIZE 16382
57 /* starting point for firmware in file 'Sc_main.mc' */
58 #define SP8870_FIRMWARE_OFFSET 0x0A
60 static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
62 u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
63 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 };
66 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
67 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
74 static int sp8870_readreg (struct sp8870_state* state, u16 reg)
77 u8 b0 [] = { reg >> 8 , reg & 0xff };
79 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
80 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
82 ret = i2c_transfer (state->i2c, msg, 2);
85 dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
89 return (b1[0] << 8 | b1[1]);
92 static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw)
95 const char *fw_buf = fw->data;
101 dprintk ("%s: ...\n", __func__);
103 if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET)
106 // system controller stop
107 sp8870_writereg(state, 0x0F00, 0x0000);
109 // instruction RAM register hiword
110 sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF));
112 // instruction RAM MWR
113 sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16));
115 // do firmware upload
116 fw_pos = SP8870_FIRMWARE_OFFSET;
117 while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){
118 tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos;
119 // write register 0xCF0A
122 memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len);
123 msg.addr = state->config->demod_address;
126 msg.len = tx_len + 2;
127 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
128 printk("%s: firmware upload failed!\n", __func__);
129 printk ("%s: i2c error (err == %i)\n", __func__, err);
135 dprintk ("%s: done!\n", __func__);
139 static void sp8870_microcontroller_stop (struct sp8870_state* state)
141 sp8870_writereg(state, 0x0F08, 0x000);
142 sp8870_writereg(state, 0x0F09, 0x000);
144 // microcontroller STOP
145 sp8870_writereg(state, 0x0F00, 0x000);
148 static void sp8870_microcontroller_start (struct sp8870_state* state)
150 sp8870_writereg(state, 0x0F08, 0x000);
151 sp8870_writereg(state, 0x0F09, 0x000);
153 // microcontroller START
154 sp8870_writereg(state, 0x0F00, 0x001);
155 // not documented but if we don't read 0x0D01 out here
156 // we don't get a correct data valid signal
157 sp8870_readreg(state, 0x0D01);
160 static int sp8870_read_data_valid_signal(struct sp8870_state* state)
162 return (sp8870_readreg(state, 0x0D02) > 0);
165 static int configure_reg0xc05 (struct dtv_frontend_properties *p, u16 *reg0xc05)
167 int known_parameters = 1;
171 switch (p->modulation) {
175 *reg0xc05 |= (1 << 10);
178 *reg0xc05 |= (2 << 10);
181 known_parameters = 0;
187 switch (p->hierarchy) {
191 *reg0xc05 |= (1 << 7);
194 *reg0xc05 |= (2 << 7);
197 *reg0xc05 |= (3 << 7);
200 known_parameters = 0;
206 switch (p->code_rate_HP) {
210 *reg0xc05 |= (1 << 3);
213 *reg0xc05 |= (2 << 3);
216 *reg0xc05 |= (3 << 3);
219 *reg0xc05 |= (4 << 3);
222 known_parameters = 0;
228 if (known_parameters)
229 *reg0xc05 |= (2 << 1); /* use specified parameters */
231 *reg0xc05 |= (1 << 1); /* enable autoprobing */
236 static int sp8870_wake_up(struct sp8870_state* state)
238 // enable TS output and interface pins
239 return sp8870_writereg(state, 0xC18, 0x00D);
242 static int sp8870_set_frontend_parameters(struct dvb_frontend *fe)
244 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
245 struct sp8870_state* state = fe->demodulator_priv;
249 if ((err = configure_reg0xc05(p, ®0xc05)))
252 // system controller stop
253 sp8870_microcontroller_stop(state);
255 // set tuner parameters
256 if (fe->ops.tuner_ops.set_params) {
257 fe->ops.tuner_ops.set_params(fe);
258 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
261 // sample rate correction bit [23..17]
262 sp8870_writereg(state, 0x0319, 0x000A);
264 // sample rate correction bit [16..0]
265 sp8870_writereg(state, 0x031A, 0x0AAB);
267 // integer carrier offset
268 sp8870_writereg(state, 0x0309, 0x0400);
270 // fractional carrier offset
271 sp8870_writereg(state, 0x030A, 0x0000);
273 // filter for 6/7/8 Mhz channel
274 if (p->bandwidth_hz == 6000000)
275 sp8870_writereg(state, 0x0311, 0x0002);
276 else if (p->bandwidth_hz == 7000000)
277 sp8870_writereg(state, 0x0311, 0x0001);
279 sp8870_writereg(state, 0x0311, 0x0000);
281 // scan order: 2k first = 0x0000, 8k first = 0x0001
282 if (p->transmission_mode == TRANSMISSION_MODE_2K)
283 sp8870_writereg(state, 0x0338, 0x0000);
285 sp8870_writereg(state, 0x0338, 0x0001);
287 sp8870_writereg(state, 0xc05, reg0xc05);
289 // read status reg in order to clear pending irqs
290 err = sp8870_readreg(state, 0x200);
294 // system controller start
295 sp8870_microcontroller_start(state);
300 static int sp8870_init (struct dvb_frontend* fe)
302 struct sp8870_state* state = fe->demodulator_priv;
303 const struct firmware *fw = NULL;
305 sp8870_wake_up(state);
306 if (state->initialised) return 0;
307 state->initialised = 1;
309 dprintk ("%s\n", __func__);
312 /* request the firmware, this will block until someone uploads it */
313 printk("sp8870: waiting for firmware upload (%s)...\n", "/*(DEBLOBBED)*/");
314 if (state->config->request_firmware(fe, &fw, "/*(DEBLOBBED)*/")) {
315 printk("sp8870: no firmware upload (timeout or file not found?)\n");
319 if (sp8870_firmware_upload(state, fw)) {
320 printk("sp8870: writing firmware to device failed\n");
321 release_firmware(fw);
324 release_firmware(fw);
325 printk("sp8870: firmware upload complete\n");
327 /* enable TS output and interface pins */
328 sp8870_writereg(state, 0xc18, 0x00d);
330 // system controller stop
331 sp8870_microcontroller_stop(state);
334 sp8870_writereg(state, 0x0301, 0x0003);
336 // Reed Solomon parity bytes passed to output
337 sp8870_writereg(state, 0x0C13, 0x0001);
339 // MPEG clock is suppressed if no valid data
340 sp8870_writereg(state, 0x0C14, 0x0001);
342 /* bit 0x010: enable data valid signal */
343 sp8870_writereg(state, 0x0D00, 0x010);
344 sp8870_writereg(state, 0x0D01, 0x000);
349 static int sp8870_read_status(struct dvb_frontend *fe,
350 enum fe_status *fe_status)
352 struct sp8870_state* state = fe->demodulator_priv;
358 status = sp8870_readreg (state, 0x0200);
362 signal = sp8870_readreg (state, 0x0303);
367 *fe_status |= FE_HAS_SIGNAL;
369 *fe_status |= FE_HAS_SYNC;
371 *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI;
376 static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
378 struct sp8870_state* state = fe->demodulator_priv;
384 ret = sp8870_readreg(state, 0xC08);
390 ret = sp8870_readreg(state, 0xC07);
403 static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
405 struct sp8870_state* state = fe->demodulator_priv;
411 ret = sp8870_readreg (state, 0x306);
417 ret = sp8870_readreg (state, 0x303);
424 *signal = 0xFFFF - tmp;
429 static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
431 struct sp8870_state* state = fe->demodulator_priv;
436 ret = sp8870_readreg(state, 0xC0C);
448 /* number of trials to recover from lockup */
450 /* maximum checks for data valid signal */
451 #define MAXCHECKS 100
453 /* only for debugging: counter for detected lockups */
455 /* only for debugging: counter for channel switches */
458 static int sp8870_set_frontend(struct dvb_frontend *fe)
460 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
461 struct sp8870_state* state = fe->demodulator_priv;
464 The firmware of the sp8870 sometimes locks up after setting frontend parameters.
465 We try to detect this by checking the data valid signal.
466 If it is not set after MAXCHECKS we try to recover the lockup by setting
467 the frontend parameters again.
475 dprintk("%s: frequency = %i\n", __func__, p->frequency);
477 for (trials = 1; trials <= MAXTRIALS; trials++) {
479 err = sp8870_set_frontend_parameters(fe);
483 for (check_count = 0; check_count < MAXCHECKS; check_count++) {
484 // valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
485 valid = sp8870_read_data_valid_signal(state);
487 dprintk("%s: delay = %i usec\n",
488 __func__, check_count * 10);
498 printk("%s: firmware crash!!!!!!\n", __func__);
505 printk("%s: firmware lockup!!!\n", __func__);
506 printk("%s: recovered after %i trial(s))\n", __func__, trials - 1);
511 printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups);
517 static int sp8870_sleep(struct dvb_frontend* fe)
519 struct sp8870_state* state = fe->demodulator_priv;
521 // tristate TS output and disable interface pins
522 return sp8870_writereg(state, 0xC18, 0x000);
525 static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
527 fesettings->min_delay_ms = 350;
528 fesettings->step_size = 0;
529 fesettings->max_drift = 0;
533 static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
535 struct sp8870_state* state = fe->demodulator_priv;
538 return sp8870_writereg(state, 0x206, 0x001);
540 return sp8870_writereg(state, 0x206, 0x000);
544 static void sp8870_release(struct dvb_frontend* fe)
546 struct sp8870_state* state = fe->demodulator_priv;
550 static struct dvb_frontend_ops sp8870_ops;
552 struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
553 struct i2c_adapter* i2c)
555 struct sp8870_state* state = NULL;
557 /* allocate memory for the internal state */
558 state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL);
559 if (state == NULL) goto error;
561 /* setup the state */
562 state->config = config;
564 state->initialised = 0;
566 /* check if the demod is there */
567 if (sp8870_readreg(state, 0x0200) < 0) goto error;
569 /* create dvb_frontend */
570 memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
571 state->frontend.demodulator_priv = state;
572 return &state->frontend;
579 static struct dvb_frontend_ops sp8870_ops = {
580 .delsys = { SYS_DVBT },
582 .name = "Spase SP8870 DVB-T",
583 .frequency_min = 470000000,
584 .frequency_max = 860000000,
585 .frequency_stepsize = 166666,
586 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
587 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
588 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
589 FE_CAN_QPSK | FE_CAN_QAM_16 |
590 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
591 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER
594 .release = sp8870_release,
597 .sleep = sp8870_sleep,
598 .i2c_gate_ctrl = sp8870_i2c_gate_ctrl,
600 .set_frontend = sp8870_set_frontend,
601 .get_tune_settings = sp8870_get_tune_settings,
603 .read_status = sp8870_read_status,
604 .read_ber = sp8870_read_ber,
605 .read_signal_strength = sp8870_read_signal_strength,
606 .read_ucblocks = sp8870_read_uncorrected_blocks,
609 module_param(debug, int, 0644);
610 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
612 MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
613 MODULE_AUTHOR("Juergen Peitz");
614 MODULE_LICENSE("GPL");
616 EXPORT_SYMBOL(sp8870_attach);