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