]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - drivers/media/dvb/frontends/sp8870.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
[linux-2.6.git] / drivers / media / dvb / frontends / sp8870.c
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/moduleparam.h>
33 #include <linux/device.h>
34 #include <linux/firmware.h>
35 #include <linux/delay.h>
36 #include <linux/string.h>
37 #include <linux/slab.h>
38
39 #include "dvb_frontend.h"
40 #include "sp8870.h"
41
42
43 struct 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
57 static 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
69 static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
70 {
71         u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
72         struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 };
73         int err;
74
75         if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
76                 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
77                 return -EREMOTEIO;
78         }
79
80         return 0;
81 }
82
83 static 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
101 static 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
148 static 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
157 static 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
169 static int sp8870_read_data_valid_signal(struct sp8870_state* state)
170 {
171         return (sp8870_readreg(state, 0x0D02) > 0);
172 }
173
174 static 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
245 static 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
251 static int sp8870_set_frontend_parameters (struct dvb_frontend* fe,
252                                            struct dvb_frontend_parameters *p)
253 {
254         struct sp8870_state* state = fe->demodulator_priv;
255         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
306 static int sp8870_init (struct dvb_frontend* fe)
307 {
308         struct sp8870_state* state = fe->demodulator_priv;
309         const struct firmware *fw = NULL;
310
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
362 static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status)
363 {
364         struct sp8870_state* state = fe->demodulator_priv;
365         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
388 static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
389 {
390         struct sp8870_state* state = fe->demodulator_priv;
391         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
416 static int sp8870_read_signal_strength(struct dvb_frontend* fe,  u16 * signal)
417 {
418         struct sp8870_state* state = fe->demodulator_priv;
419         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
442 static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
443 {
444         struct sp8870_state* state = fe->demodulator_priv;
445         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
467 static int lockups = 0;
468 // only for debugging: counter for channel switches
469 static int switches = 0;
470
471 static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
472 {
473         struct sp8870_state* state = fe->demodulator_priv;
474
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
528 static int sp8870_sleep(struct dvb_frontend* fe)
529 {
530         struct sp8870_state* state = fe->demodulator_priv;
531
532         // tristate TS output and disable interface pins
533         return sp8870_writereg(state, 0xC18, 0x000);
534 }
535
536 static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
537 {
538         fesettings->min_delay_ms = 350;
539         fesettings->step_size = 0;
540         fesettings->max_drift = 0;
541         return 0;
542 }
543
544 static void sp8870_release(struct dvb_frontend* fe)
545 {
546         struct sp8870_state* state = fe->demodulator_priv;
547         kfree(state);
548 }
549
550 static struct dvb_frontend_ops sp8870_ops;
551
552 struct 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 */
558         state = kmalloc(sizeof(struct sp8870_state), GFP_KERNEL);
559         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
575 error:
576         kfree(state);
577         return NULL;
578 }
579
580 static 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
610 module_param(debug, int, 0644);
611 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
612
613 MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
614 MODULE_AUTHOR("Juergen Peitz");
615 MODULE_LICENSE("GPL");
616
617 EXPORT_SYMBOL(sp8870_attach);