blob: 73829e647e50ad0cccb0e2f8cf6f8b18ada520ff [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
265 sp8870_writereg(state, 0x206, 0x001);
266 state->config->pll_set(fe, p);
267 sp8870_writereg(state, 0x206, 0x000);
268
269 // sample rate correction bit [23..17]
270 sp8870_writereg(state, 0x0319, 0x000A);
271
272 // sample rate correction bit [16..0]
273 sp8870_writereg(state, 0x031A, 0x0AAB);
274
275 // integer carrier offset
276 sp8870_writereg(state, 0x0309, 0x0400);
277
278 // fractional carrier offset
279 sp8870_writereg(state, 0x030A, 0x0000);
280
281 // filter for 6/7/8 Mhz channel
282 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
283 sp8870_writereg(state, 0x0311, 0x0002);
284 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
285 sp8870_writereg(state, 0x0311, 0x0001);
286 else
287 sp8870_writereg(state, 0x0311, 0x0000);
288
289 // scan order: 2k first = 0x0000, 8k first = 0x0001
290 if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K)
291 sp8870_writereg(state, 0x0338, 0x0000);
292 else
293 sp8870_writereg(state, 0x0338, 0x0001);
294
295 sp8870_writereg(state, 0xc05, reg0xc05);
296
297 // read status reg in order to clear pending irqs
298 sp8870_readreg(state, 0x200);
299
300 // system controller start
301 sp8870_microcontroller_start(state);
302
303 return 0;
304}
305
306static int sp8870_init (struct dvb_frontend* fe)
307{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700308 struct sp8870_state* state = fe->demodulator_priv;
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -0800309 const struct firmware *fw = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310
311 sp8870_wake_up(state);
312 if (state->initialised) return 0;
313 state->initialised = 1;
314
315 dprintk ("%s\n", __FUNCTION__);
316
317
318 /* request the firmware, this will block until someone uploads it */
319 printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
320 if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
321 printk("sp8870: no firmware upload (timeout or file not found?)\n");
322 release_firmware(fw);
323 return -EIO;
324 }
325
326 if (sp8870_firmware_upload(state, fw)) {
327 printk("sp8870: writing firmware to device failed\n");
328 release_firmware(fw);
329 return -EIO;
330 }
331 printk("sp8870: firmware upload complete\n");
332
333 /* enable TS output and interface pins */
334 sp8870_writereg(state, 0xc18, 0x00d);
335
336 // system controller stop
337 sp8870_microcontroller_stop(state);
338
339 // ADC mode
340 sp8870_writereg(state, 0x0301, 0x0003);
341
342 // Reed Solomon parity bytes passed to output
343 sp8870_writereg(state, 0x0C13, 0x0001);
344
345 // MPEG clock is suppressed if no valid data
346 sp8870_writereg(state, 0x0C14, 0x0001);
347
348 /* bit 0x010: enable data valid signal */
349 sp8870_writereg(state, 0x0D00, 0x010);
350 sp8870_writereg(state, 0x0D01, 0x000);
351
352 /* setup PLL */
353 if (state->config->pll_init) {
354 sp8870_writereg(state, 0x206, 0x001);
355 state->config->pll_init(fe);
356 sp8870_writereg(state, 0x206, 0x000);
357 }
358
359 return 0;
360}
361
362static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status)
363{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700364 struct sp8870_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 int status;
366 int signal;
367
368 *fe_status = 0;
369
370 status = sp8870_readreg (state, 0x0200);
371 if (status < 0)
372 return -EIO;
373
374 signal = sp8870_readreg (state, 0x0303);
375 if (signal < 0)
376 return -EIO;
377
378 if (signal > 0x0F)
379 *fe_status |= FE_HAS_SIGNAL;
380 if (status & 0x08)
381 *fe_status |= FE_HAS_SYNC;
382 if (status & 0x04)
383 *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI;
384
385 return 0;
386}
387
388static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
389{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700390 struct sp8870_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 int ret;
392 u32 tmp;
393
394 *ber = 0;
395
396 ret = sp8870_readreg(state, 0xC08);
397 if (ret < 0)
398 return -EIO;
399
400 tmp = ret & 0x3F;
401
402 ret = sp8870_readreg(state, 0xC07);
403 if (ret < 0)
404 return -EIO;
405
406 tmp = ret << 6;
407
408 if (tmp >= 0x3FFF0)
409 tmp = ~0;
410
411 *ber = tmp;
412
413 return 0;
414}
415
416static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
417{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700418 struct sp8870_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 int ret;
420 u16 tmp;
421
422 *signal = 0;
423
424 ret = sp8870_readreg (state, 0x306);
425 if (ret < 0)
426 return -EIO;
427
428 tmp = ret << 8;
429
430 ret = sp8870_readreg (state, 0x303);
431 if (ret < 0)
432 return -EIO;
433
434 tmp |= ret;
435
436 if (tmp)
437 *signal = 0xFFFF - tmp;
438
439 return 0;
440}
441
442static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
443{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700444 struct sp8870_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 int ret;
446
447 *ublocks = 0;
448
449 ret = sp8870_readreg(state, 0xC0C);
450 if (ret < 0)
451 return -EIO;
452
453 if (ret == 0xFFFF)
454 ret = ~0;
455
456 *ublocks = ret;
457
458 return 0;
459}
460
461// number of trials to recover from lockup
462#define MAXTRIALS 5
463// maximum checks for data valid signal
464#define MAXCHECKS 100
465
466// only for debugging: counter for detected lockups
467static int lockups = 0;
468// only for debugging: counter for channel switches
469static int switches = 0;
470
471static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
472{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700473 struct sp8870_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474
475 /*
476 The firmware of the sp8870 sometimes locks up after setting frontend parameters.
477 We try to detect this by checking the data valid signal.
478 If it is not set after MAXCHECKS we try to recover the lockup by setting
479 the frontend parameters again.
480 */
481
482 int err = 0;
483 int valid = 0;
484 int trials = 0;
485 int check_count = 0;
486
487 dprintk("%s: frequency = %i\n", __FUNCTION__, p->frequency);
488
489 for (trials = 1; trials <= MAXTRIALS; trials++) {
490
491 if ((err = sp8870_set_frontend_parameters(fe, p)))
492 return err;
493
494 for (check_count = 0; check_count < MAXCHECKS; check_count++) {
495// valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
496 valid = sp8870_read_data_valid_signal(state);
497 if (valid) {
498 dprintk("%s: delay = %i usec\n",
499 __FUNCTION__, check_count * 10);
500 break;
501 }
502 udelay(10);
503 }
504 if (valid)
505 break;
506 }
507
508 if (!valid) {
509 printk("%s: firmware crash!!!!!!\n", __FUNCTION__);
510 return -EIO;
511 }
512
513 if (debug) {
514 if (valid) {
515 if (trials > 1) {
516 printk("%s: firmware lockup!!!\n", __FUNCTION__);
517 printk("%s: recovered after %i trial(s))\n", __FUNCTION__, trials - 1);
518 lockups++;
519 }
520 }
521 switches++;
522 printk("%s: switches = %i lockups = %i\n", __FUNCTION__, switches, lockups);
523 }
524
525 return 0;
526}
527
528static int sp8870_sleep(struct dvb_frontend* fe)
529{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700530 struct sp8870_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531
532 // tristate TS output and disable interface pins
533 return sp8870_writereg(state, 0xC18, 0x000);
534}
535
536static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
537{
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -0800538 fesettings->min_delay_ms = 350;
539 fesettings->step_size = 0;
540 fesettings->max_drift = 0;
541 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542}
543
544static void sp8870_release(struct dvb_frontend* fe)
545{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700546 struct sp8870_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 kfree(state);
548}
549
550static struct dvb_frontend_ops sp8870_ops;
551
552struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
553 struct i2c_adapter* i2c)
554{
555 struct sp8870_state* state = NULL;
556
557 /* allocate memory for the internal state */
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700558 state = kmalloc(sizeof(struct sp8870_state), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 if (state == NULL) goto error;
560
561 /* setup the state */
562 state->config = config;
563 state->i2c = i2c;
564 memcpy(&state->ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
565 state->initialised = 0;
566
567 /* check if the demod is there */
568 if (sp8870_readreg(state, 0x0200) < 0) goto error;
569
570 /* create dvb_frontend */
571 state->frontend.ops = &state->ops;
572 state->frontend.demodulator_priv = state;
573 return &state->frontend;
574
575error:
576 kfree(state);
577 return NULL;
578}
579
580static struct dvb_frontend_ops sp8870_ops = {
581
582 .info = {
583 .name = "Spase SP8870 DVB-T",
584 .type = FE_OFDM,
585 .frequency_min = 470000000,
586 .frequency_max = 860000000,
587 .frequency_stepsize = 166666,
588 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
589 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
590 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
591 FE_CAN_QPSK | FE_CAN_QAM_16 |
592 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
593 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER
594 },
595
596 .release = sp8870_release,
597
598 .init = sp8870_init,
599 .sleep = sp8870_sleep,
600
601 .set_frontend = sp8870_set_frontend,
602 .get_tune_settings = sp8870_get_tune_settings,
603
604 .read_status = sp8870_read_status,
605 .read_ber = sp8870_read_ber,
606 .read_signal_strength = sp8870_read_signal_strength,
607 .read_ucblocks = sp8870_read_uncorrected_blocks,
608};
609
610module_param(debug, int, 0644);
611MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
612
613MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
614MODULE_AUTHOR("Juergen Peitz");
615MODULE_LICENSE("GPL");
616
617EXPORT_SYMBOL(sp8870_attach);