Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
[pandora-kernel.git] / drivers / media / dvb / frontends / mb86a20s.c
1 /*
2  *   Fujitu mb86a20s ISDB-T/ISDB-Tsb Module driver
3  *
4  *   Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
5  *   Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
6  *
7  *   FIXME: Need to port to DVB v5.2 API
8  *
9  *   This program is free software; you can redistribute it and/or
10  *   modify it under the terms of the GNU General Public License as
11  *   published by the Free Software Foundation version 2.
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *   General Public License for more details.
17  */
18
19 #include <linux/kernel.h>
20 #include <asm/div64.h>
21
22 #include "dvb_frontend.h"
23 #include "mb86a20s.h"
24
25 static int debug = 1;
26 module_param(debug, int, 0644);
27 MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
28
29 #define rc(args...)  do {                                               \
30         printk(KERN_ERR  "mb86a20s: " args);                            \
31 } while (0)
32
33 #define dprintk(args...)                                                \
34         do {                                                            \
35                 if (debug) {                                            \
36                         printk(KERN_DEBUG "mb86a20s: %s: ", __func__);  \
37                         printk(args);                                   \
38                 }                                                       \
39         } while (0)
40
41 struct mb86a20s_state {
42         struct i2c_adapter *i2c;
43         const struct mb86a20s_config *config;
44
45         struct dvb_frontend frontend;
46 };
47
48 struct regdata {
49         u8 reg;
50         u8 data;
51 };
52
53 /*
54  * Initialization sequence: Use whatevere default values that PV SBTVD
55  * does on its initialisation, obtained via USB snoop
56  */
57 static struct regdata mb86a20s_init[] = {
58         { 0x70, 0x0f },
59         { 0x70, 0xff },
60         { 0x08, 0x01 },
61         { 0x09, 0x3e },
62         { 0x50, 0xd1 },
63         { 0x51, 0x22 },
64         { 0x39, 0x01 },
65         { 0x71, 0x00 },
66         { 0x28, 0x2a },
67         { 0x29, 0x00 },
68         { 0x2a, 0xff },
69         { 0x2b, 0x80 },
70         { 0x28, 0x20 },
71         { 0x29, 0x33 },
72         { 0x2a, 0xdf },
73         { 0x2b, 0xa9 },
74         { 0x3b, 0x21 },
75         { 0x3c, 0x3a },
76         { 0x01, 0x0d },
77         { 0x04, 0x08 },
78         { 0x05, 0x05 },
79         { 0x04, 0x0e },
80         { 0x05, 0x00 },
81         { 0x04, 0x0f },
82         { 0x05, 0x14 },
83         { 0x04, 0x0b },
84         { 0x05, 0x8c },
85         { 0x04, 0x00 },
86         { 0x05, 0x00 },
87         { 0x04, 0x01 },
88         { 0x05, 0x07 },
89         { 0x04, 0x02 },
90         { 0x05, 0x0f },
91         { 0x04, 0x03 },
92         { 0x05, 0xa0 },
93         { 0x04, 0x09 },
94         { 0x05, 0x00 },
95         { 0x04, 0x0a },
96         { 0x05, 0xff },
97         { 0x04, 0x27 },
98         { 0x05, 0x64 },
99         { 0x04, 0x28 },
100         { 0x05, 0x00 },
101         { 0x04, 0x1e },
102         { 0x05, 0xff },
103         { 0x04, 0x29 },
104         { 0x05, 0x0a },
105         { 0x04, 0x32 },
106         { 0x05, 0x0a },
107         { 0x04, 0x14 },
108         { 0x05, 0x02 },
109         { 0x04, 0x04 },
110         { 0x05, 0x00 },
111         { 0x04, 0x05 },
112         { 0x05, 0x22 },
113         { 0x04, 0x06 },
114         { 0x05, 0x0e },
115         { 0x04, 0x07 },
116         { 0x05, 0xd8 },
117         { 0x04, 0x12 },
118         { 0x05, 0x00 },
119         { 0x04, 0x13 },
120         { 0x05, 0xff },
121         { 0x52, 0x01 },
122         { 0x50, 0xa7 },
123         { 0x51, 0x00 },
124         { 0x50, 0xa8 },
125         { 0x51, 0xff },
126         { 0x50, 0xa9 },
127         { 0x51, 0xff },
128         { 0x50, 0xaa },
129         { 0x51, 0x00 },
130         { 0x50, 0xab },
131         { 0x51, 0xff },
132         { 0x50, 0xac },
133         { 0x51, 0xff },
134         { 0x50, 0xad },
135         { 0x51, 0x00 },
136         { 0x50, 0xae },
137         { 0x51, 0xff },
138         { 0x50, 0xaf },
139         { 0x51, 0xff },
140         { 0x5e, 0x07 },
141         { 0x50, 0xdc },
142         { 0x51, 0x01 },
143         { 0x50, 0xdd },
144         { 0x51, 0xf4 },
145         { 0x50, 0xde },
146         { 0x51, 0x01 },
147         { 0x50, 0xdf },
148         { 0x51, 0xf4 },
149         { 0x50, 0xe0 },
150         { 0x51, 0x01 },
151         { 0x50, 0xe1 },
152         { 0x51, 0xf4 },
153         { 0x50, 0xb0 },
154         { 0x51, 0x07 },
155         { 0x50, 0xb2 },
156         { 0x51, 0xff },
157         { 0x50, 0xb3 },
158         { 0x51, 0xff },
159         { 0x50, 0xb4 },
160         { 0x51, 0xff },
161         { 0x50, 0xb5 },
162         { 0x51, 0xff },
163         { 0x50, 0xb6 },
164         { 0x51, 0xff },
165         { 0x50, 0xb7 },
166         { 0x51, 0xff },
167         { 0x50, 0x50 },
168         { 0x51, 0x02 },
169         { 0x50, 0x51 },
170         { 0x51, 0x04 },
171         { 0x45, 0x04 },
172         { 0x48, 0x04 },
173         { 0x50, 0xd5 },
174         { 0x51, 0x01 },         /* Serial */
175         { 0x50, 0xd6 },
176         { 0x51, 0x1f },
177         { 0x50, 0xd2 },
178         { 0x51, 0x03 },
179         { 0x50, 0xd7 },
180         { 0x51, 0x3f },
181         { 0x1c, 0x01 },
182         { 0x28, 0x06 },
183         { 0x29, 0x00 },
184         { 0x2a, 0x00 },
185         { 0x2b, 0x03 },
186         { 0x28, 0x07 },
187         { 0x29, 0x00 },
188         { 0x2a, 0x00 },
189         { 0x2b, 0x0d },
190         { 0x28, 0x08 },
191         { 0x29, 0x00 },
192         { 0x2a, 0x00 },
193         { 0x2b, 0x02 },
194         { 0x28, 0x09 },
195         { 0x29, 0x00 },
196         { 0x2a, 0x00 },
197         { 0x2b, 0x01 },
198         { 0x28, 0x0a },
199         { 0x29, 0x00 },
200         { 0x2a, 0x00 },
201         { 0x2b, 0x21 },
202         { 0x28, 0x0b },
203         { 0x29, 0x00 },
204         { 0x2a, 0x00 },
205         { 0x2b, 0x29 },
206         { 0x28, 0x0c },
207         { 0x29, 0x00 },
208         { 0x2a, 0x00 },
209         { 0x2b, 0x16 },
210         { 0x28, 0x0d },
211         { 0x29, 0x00 },
212         { 0x2a, 0x00 },
213         { 0x2b, 0x31 },
214         { 0x28, 0x0e },
215         { 0x29, 0x00 },
216         { 0x2a, 0x00 },
217         { 0x2b, 0x0e },
218         { 0x28, 0x0f },
219         { 0x29, 0x00 },
220         { 0x2a, 0x00 },
221         { 0x2b, 0x4e },
222         { 0x28, 0x10 },
223         { 0x29, 0x00 },
224         { 0x2a, 0x00 },
225         { 0x2b, 0x46 },
226         { 0x28, 0x11 },
227         { 0x29, 0x00 },
228         { 0x2a, 0x00 },
229         { 0x2b, 0x0f },
230         { 0x28, 0x12 },
231         { 0x29, 0x00 },
232         { 0x2a, 0x00 },
233         { 0x2b, 0x56 },
234         { 0x28, 0x13 },
235         { 0x29, 0x00 },
236         { 0x2a, 0x00 },
237         { 0x2b, 0x35 },
238         { 0x28, 0x14 },
239         { 0x29, 0x00 },
240         { 0x2a, 0x01 },
241         { 0x2b, 0xbe },
242         { 0x28, 0x15 },
243         { 0x29, 0x00 },
244         { 0x2a, 0x01 },
245         { 0x2b, 0x84 },
246         { 0x28, 0x16 },
247         { 0x29, 0x00 },
248         { 0x2a, 0x03 },
249         { 0x2b, 0xee },
250         { 0x28, 0x17 },
251         { 0x29, 0x00 },
252         { 0x2a, 0x00 },
253         { 0x2b, 0x98 },
254         { 0x28, 0x18 },
255         { 0x29, 0x00 },
256         { 0x2a, 0x00 },
257         { 0x2b, 0x9f },
258         { 0x28, 0x19 },
259         { 0x29, 0x00 },
260         { 0x2a, 0x07 },
261         { 0x2b, 0xb2 },
262         { 0x28, 0x1a },
263         { 0x29, 0x00 },
264         { 0x2a, 0x06 },
265         { 0x2b, 0xc2 },
266         { 0x28, 0x1b },
267         { 0x29, 0x00 },
268         { 0x2a, 0x07 },
269         { 0x2b, 0x4a },
270         { 0x28, 0x1c },
271         { 0x29, 0x00 },
272         { 0x2a, 0x01 },
273         { 0x2b, 0xbc },
274         { 0x28, 0x1d },
275         { 0x29, 0x00 },
276         { 0x2a, 0x04 },
277         { 0x2b, 0xba },
278         { 0x28, 0x1e },
279         { 0x29, 0x00 },
280         { 0x2a, 0x06 },
281         { 0x2b, 0x14 },
282         { 0x50, 0x1e },
283         { 0x51, 0x5d },
284         { 0x50, 0x22 },
285         { 0x51, 0x00 },
286         { 0x50, 0x23 },
287         { 0x51, 0xc8 },
288         { 0x50, 0x24 },
289         { 0x51, 0x00 },
290         { 0x50, 0x25 },
291         { 0x51, 0xf0 },
292         { 0x50, 0x26 },
293         { 0x51, 0x00 },
294         { 0x50, 0x27 },
295         { 0x51, 0xc3 },
296         { 0x50, 0x39 },
297         { 0x51, 0x02 },
298         { 0x50, 0xd5 },
299         { 0x51, 0x01 },
300         { 0xd0, 0x00 },
301 };
302
303 static struct regdata mb86a20s_reset_reception[] = {
304         { 0x70, 0xf0 },
305         { 0x70, 0xff },
306         { 0x08, 0x01 },
307         { 0x08, 0x00 },
308 };
309
310 static int mb86a20s_i2c_writereg(struct mb86a20s_state *state,
311                              u8 i2c_addr, int reg, int data)
312 {
313         u8 buf[] = { reg, data };
314         struct i2c_msg msg = {
315                 .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
316         };
317         int rc;
318
319         rc = i2c_transfer(state->i2c, &msg, 1);
320         if (rc != 1) {
321                 printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
322                          " data == 0x%02x)\n", __func__, rc, reg, data);
323                 return rc;
324         }
325
326         return 0;
327 }
328
329 static int mb86a20s_i2c_writeregdata(struct mb86a20s_state *state,
330                                      u8 i2c_addr, struct regdata *rd, int size)
331 {
332         int i, rc;
333
334         for (i = 0; i < size; i++) {
335                 rc = mb86a20s_i2c_writereg(state, i2c_addr, rd[i].reg,
336                                            rd[i].data);
337                 if (rc < 0)
338                         return rc;
339         }
340         return 0;
341 }
342
343 static int mb86a20s_i2c_readreg(struct mb86a20s_state *state,
344                                 u8 i2c_addr, u8 reg)
345 {
346         u8 val;
347         int rc;
348         struct i2c_msg msg[] = {
349                 { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
350                 { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
351         };
352
353         rc = i2c_transfer(state->i2c, msg, 2);
354
355         if (rc != 2) {
356                 rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
357                 return rc;
358         }
359
360         return val;
361 }
362
363 #define mb86a20s_readreg(state, reg) \
364         mb86a20s_i2c_readreg(state, state->config->demod_address, reg)
365 #define mb86a20s_writereg(state, reg, val) \
366         mb86a20s_i2c_writereg(state, state->config->demod_address, reg, val)
367 #define mb86a20s_writeregdata(state, regdata) \
368         mb86a20s_i2c_writeregdata(state, state->config->demod_address, \
369         regdata, ARRAY_SIZE(regdata))
370
371 static int mb86a20s_initfe(struct dvb_frontend *fe)
372 {
373         struct mb86a20s_state *state = fe->demodulator_priv;
374         int rc;
375         u8  regD5 = 1;
376
377         dprintk("\n");
378
379         if (fe->ops.i2c_gate_ctrl)
380                 fe->ops.i2c_gate_ctrl(fe, 0);
381
382         /* Initialize the frontend */
383         rc = mb86a20s_writeregdata(state, mb86a20s_init);
384         if (rc < 0)
385                 return rc;
386
387         if (!state->config->is_serial) {
388                 regD5 &= ~1;
389
390                 rc = mb86a20s_writereg(state, 0x50, 0xd5);
391                 if (rc < 0)
392                         return rc;
393                 rc = mb86a20s_writereg(state, 0x51, regD5);
394                 if (rc < 0)
395                         return rc;
396         }
397
398         if (fe->ops.i2c_gate_ctrl)
399                 fe->ops.i2c_gate_ctrl(fe, 1);
400
401         return 0;
402 }
403
404 static int mb86a20s_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
405 {
406         struct mb86a20s_state *state = fe->demodulator_priv;
407         unsigned rf_max, rf_min, rf;
408         u8       val;
409
410         dprintk("\n");
411
412         if (fe->ops.i2c_gate_ctrl)
413                 fe->ops.i2c_gate_ctrl(fe, 0);
414
415         /* Does a binary search to get RF strength */
416         rf_max = 0xfff;
417         rf_min = 0;
418         do {
419                 rf = (rf_max + rf_min) / 2;
420                 mb86a20s_writereg(state, 0x04, 0x1f);
421                 mb86a20s_writereg(state, 0x05, rf >> 8);
422                 mb86a20s_writereg(state, 0x04, 0x20);
423                 mb86a20s_writereg(state, 0x04, rf);
424
425                 val = mb86a20s_readreg(state, 0x02);
426                 if (val & 0x08)
427                         rf_min = (rf_max + rf_min) / 2;
428                 else
429                         rf_max = (rf_max + rf_min) / 2;
430                 if (rf_max - rf_min < 4) {
431                         *strength = (((rf_max + rf_min) / 2) * 65535) / 4095;
432                         break;
433                 }
434         } while (1);
435
436         dprintk("signal strength = %d\n", *strength);
437
438         if (fe->ops.i2c_gate_ctrl)
439                 fe->ops.i2c_gate_ctrl(fe, 1);
440
441         return 0;
442 }
443
444 static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status)
445 {
446         struct mb86a20s_state *state = fe->demodulator_priv;
447         u8 val;
448
449         dprintk("\n");
450         *status = 0;
451
452         if (fe->ops.i2c_gate_ctrl)
453                 fe->ops.i2c_gate_ctrl(fe, 0);
454         val = mb86a20s_readreg(state, 0x0a) & 0xf;
455         if (fe->ops.i2c_gate_ctrl)
456                 fe->ops.i2c_gate_ctrl(fe, 1);
457
458         if (val >= 2)
459                 *status |= FE_HAS_SIGNAL;
460
461         if (val >= 4)
462                 *status |= FE_HAS_CARRIER;
463
464         if (val >= 5)
465                 *status |= FE_HAS_VITERBI;
466
467         if (val >= 7)
468                 *status |= FE_HAS_SYNC;
469
470         if (val >= 8)                           /* Maybe 9? */
471                 *status |= FE_HAS_LOCK;
472
473         dprintk("val = %d, status = 0x%02x\n", val, *status);
474
475         return 0;
476 }
477
478 static int mb86a20s_set_frontend(struct dvb_frontend *fe,
479         struct dvb_frontend_parameters *p)
480 {
481         struct mb86a20s_state *state = fe->demodulator_priv;
482         int rc;
483
484         dprintk("\n");
485
486         if (fe->ops.i2c_gate_ctrl)
487                 fe->ops.i2c_gate_ctrl(fe, 1);
488         fe->ops.tuner_ops.set_params(fe, p);
489
490         if (fe->ops.i2c_gate_ctrl)
491                 fe->ops.i2c_gate_ctrl(fe, 0);
492         rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception);
493         if (fe->ops.i2c_gate_ctrl)
494                 fe->ops.i2c_gate_ctrl(fe, 1);
495
496         return rc;
497 }
498
499 static int mb86a20s_get_frontend(struct dvb_frontend *fe,
500         struct dvb_frontend_parameters *p)
501 {
502
503         /* FIXME: For now, it does nothing */
504
505         fe->dtv_property_cache.bandwidth_hz = 6000000;
506         fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
507         fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
508         fe->dtv_property_cache.isdbt_partial_reception = 0;
509
510         return 0;
511 }
512
513 static int mb86a20s_tune(struct dvb_frontend *fe,
514                         struct dvb_frontend_parameters *params,
515                         unsigned int mode_flags,
516                         unsigned int *delay,
517                         fe_status_t *status)
518 {
519         int rc = 0;
520
521         dprintk("\n");
522
523         if (params != NULL)
524                 rc = mb86a20s_set_frontend(fe, params);
525
526         if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
527                 mb86a20s_read_status(fe, status);
528
529         return rc;
530 }
531
532 static void mb86a20s_release(struct dvb_frontend *fe)
533 {
534         struct mb86a20s_state *state = fe->demodulator_priv;
535
536         dprintk("\n");
537
538         kfree(state);
539 }
540
541 static struct dvb_frontend_ops mb86a20s_ops;
542
543 struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
544                                     struct i2c_adapter *i2c)
545 {
546         u8      rev;
547
548         /* allocate memory for the internal state */
549         struct mb86a20s_state *state =
550                 kzalloc(sizeof(struct mb86a20s_state), GFP_KERNEL);
551
552         dprintk("\n");
553         if (state == NULL) {
554                 rc("Unable to kzalloc\n");
555                 goto error;
556         }
557
558         /* setup the state */
559         state->config = config;
560         state->i2c = i2c;
561
562         /* create dvb_frontend */
563         memcpy(&state->frontend.ops, &mb86a20s_ops,
564                 sizeof(struct dvb_frontend_ops));
565         state->frontend.demodulator_priv = state;
566
567         /* Check if it is a mb86a20s frontend */
568         rev = mb86a20s_readreg(state, 0);
569
570         if (rev == 0x13) {
571                 printk(KERN_INFO "Detected a Fujitsu mb86a20s frontend\n");
572         } else {
573                 printk(KERN_ERR "Frontend revision %d is unknown - aborting.\n",
574                        rev);
575                 goto error;
576         }
577
578         return &state->frontend;
579
580 error:
581         kfree(state);
582         return NULL;
583 }
584 EXPORT_SYMBOL(mb86a20s_attach);
585
586 static struct dvb_frontend_ops mb86a20s_ops = {
587         /* Use dib8000 values per default */
588         .info = {
589                 .name = "Fujitsu mb86A20s",
590                 .type = FE_OFDM,
591                 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_RECOVER |
592                         FE_CAN_FEC_1_2  | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
593                         FE_CAN_FEC_5_6  | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
594                         FE_CAN_QPSK     | FE_CAN_QAM_16  | FE_CAN_QAM_64 |
595                         FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_QAM_AUTO |
596                         FE_CAN_GUARD_INTERVAL_AUTO    | FE_CAN_HIERARCHY_AUTO,
597                 /* Actually, those values depend on the used tuner */
598                 .frequency_min = 45000000,
599                 .frequency_max = 864000000,
600                 .frequency_stepsize = 62500,
601         },
602
603         .release = mb86a20s_release,
604
605         .init = mb86a20s_initfe,
606         .set_frontend = mb86a20s_set_frontend,
607         .get_frontend = mb86a20s_get_frontend,
608         .read_status = mb86a20s_read_status,
609         .read_signal_strength = mb86a20s_read_signal_strength,
610         .tune = mb86a20s_tune,
611 };
612
613 MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware");
614 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
615 MODULE_LICENSE("GPL");