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