Merge branch 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / drivers / media / dvb-frontends / s921.c
1 /*
2  *   Sharp VA3A5JZ921 One Seg Broadcast Module driver
3  *   This device is labeled as just S. 921 at the top of the frontend can
4  *
5  *   Copyright (C) 2009-2010 Mauro Carvalho Chehab
6  *   Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
7  *
8  *   Developed for Leadership SBTVD 1seg device sold in Brazil
9  *
10  *   Frontend module based on cx24123 driver, getting some info from
11  *      the old s921 driver.
12  *
13  *   FIXME: Need to port to DVB v5.2 API
14  *
15  *   This program is free software; you can redistribute it and/or
16  *   modify it under the terms of the GNU General Public License as
17  *   published by the Free Software Foundation version 2.
18  *
19  *   This program is distributed in the hope that it will be useful,
20  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22  *   General Public License for more details.
23  */
24
25 #include <linux/kernel.h>
26 #include <asm/div64.h>
27
28 #include "dvb_frontend.h"
29 #include "s921.h"
30
31 static int debug = 1;
32 module_param(debug, int, 0644);
33 MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
34
35 #define rc(args...)  do {                                               \
36         printk(KERN_ERR  "s921: " args);                                \
37 } while (0)
38
39 #define dprintk(args...)                                                \
40         do {                                                            \
41                 if (debug) {                                            \
42                         printk(KERN_DEBUG "s921: %s: ", __func__);      \
43                         printk(args);                                   \
44                 }                                                       \
45         } while (0)
46
47 struct s921_state {
48         struct i2c_adapter *i2c;
49         const struct s921_config *config;
50
51         struct dvb_frontend frontend;
52
53         /* The Demod can't easily provide these, we cache them */
54         u32 currentfreq;
55 };
56
57 /*
58  * Various tuner defaults need to be established for a given frequency kHz.
59  * fixme: The bounds on the bands do not match the doc in real life.
60  * fixme: Some of them have been moved, other might need adjustment.
61  */
62 static struct s921_bandselect_val {
63         u32 freq_low;
64         u8  band_reg;
65 } s921_bandselect[] = {
66         {         0, 0x7b },
67         { 485140000, 0x5b },
68         { 515140000, 0x3b },
69         { 545140000, 0x1b },
70         { 599140000, 0xfb },
71         { 623140000, 0xdb },
72         { 659140000, 0xbb },
73         { 713140000, 0x9b },
74 };
75
76 struct regdata {
77         u8 reg;
78         u8 data;
79 };
80
81 static struct regdata s921_init[] = {
82         { 0x01, 0x80 },         /* Probably, a reset sequence */
83         { 0x01, 0x40 },
84         { 0x01, 0x80 },
85         { 0x01, 0x40 },
86
87         { 0x02, 0x00 },
88         { 0x03, 0x40 },
89         { 0x04, 0x01 },
90         { 0x05, 0x00 },
91         { 0x06, 0x00 },
92         { 0x07, 0x00 },
93         { 0x08, 0x00 },
94         { 0x09, 0x00 },
95         { 0x0a, 0x00 },
96         { 0x0b, 0x5a },
97         { 0x0c, 0x00 },
98         { 0x0d, 0x00 },
99         { 0x0f, 0x00 },
100         { 0x13, 0x1b },
101         { 0x14, 0x80 },
102         { 0x15, 0x40 },
103         { 0x17, 0x70 },
104         { 0x18, 0x01 },
105         { 0x19, 0x12 },
106         { 0x1a, 0x01 },
107         { 0x1b, 0x12 },
108         { 0x1c, 0xa0 },
109         { 0x1d, 0x00 },
110         { 0x1e, 0x0a },
111         { 0x1f, 0x08 },
112         { 0x20, 0x40 },
113         { 0x21, 0xff },
114         { 0x22, 0x4c },
115         { 0x23, 0x4e },
116         { 0x24, 0x4c },
117         { 0x25, 0x00 },
118         { 0x26, 0x00 },
119         { 0x27, 0xf4 },
120         { 0x28, 0x60 },
121         { 0x29, 0x88 },
122         { 0x2a, 0x40 },
123         { 0x2b, 0x40 },
124         { 0x2c, 0xff },
125         { 0x2d, 0x00 },
126         { 0x2e, 0xff },
127         { 0x2f, 0x00 },
128         { 0x30, 0x20 },
129         { 0x31, 0x06 },
130         { 0x32, 0x0c },
131         { 0x34, 0x0f },
132         { 0x37, 0xfe },
133         { 0x38, 0x00 },
134         { 0x39, 0x63 },
135         { 0x3a, 0x10 },
136         { 0x3b, 0x10 },
137         { 0x47, 0x00 },
138         { 0x49, 0xe5 },
139         { 0x4b, 0x00 },
140         { 0x50, 0xc0 },
141         { 0x52, 0x20 },
142         { 0x54, 0x5a },
143         { 0x55, 0x5b },
144         { 0x56, 0x40 },
145         { 0x57, 0x70 },
146         { 0x5c, 0x50 },
147         { 0x5d, 0x00 },
148         { 0x62, 0x17 },
149         { 0x63, 0x2f },
150         { 0x64, 0x6f },
151         { 0x68, 0x00 },
152         { 0x69, 0x89 },
153         { 0x6a, 0x00 },
154         { 0x6b, 0x00 },
155         { 0x6c, 0x00 },
156         { 0x6d, 0x00 },
157         { 0x6e, 0x00 },
158         { 0x70, 0x10 },
159         { 0x71, 0x00 },
160         { 0x75, 0x00 },
161         { 0x76, 0x30 },
162         { 0x77, 0x01 },
163         { 0xaf, 0x00 },
164         { 0xb0, 0xa0 },
165         { 0xb2, 0x3d },
166         { 0xb3, 0x25 },
167         { 0xb4, 0x8b },
168         { 0xb5, 0x4b },
169         { 0xb6, 0x3f },
170         { 0xb7, 0xff },
171         { 0xb8, 0xff },
172         { 0xb9, 0xfc },
173         { 0xba, 0x00 },
174         { 0xbb, 0x00 },
175         { 0xbc, 0x00 },
176         { 0xd0, 0x30 },
177         { 0xe4, 0x84 },
178         { 0xf0, 0x48 },
179         { 0xf1, 0x19 },
180         { 0xf2, 0x5a },
181         { 0xf3, 0x8e },
182         { 0xf4, 0x2d },
183         { 0xf5, 0x07 },
184         { 0xf6, 0x5a },
185         { 0xf7, 0xba },
186         { 0xf8, 0xd7 },
187 };
188
189 static struct regdata s921_prefreq[] = {
190         { 0x47, 0x60 },
191         { 0x68, 0x00 },
192         { 0x69, 0x89 },
193         { 0xf0, 0x48 },
194         { 0xf1, 0x19 },
195 };
196
197 static struct regdata s921_postfreq[] = {
198         { 0xf5, 0xae },
199         { 0xf6, 0xb7 },
200         { 0xf7, 0xba },
201         { 0xf8, 0xd7 },
202         { 0x68, 0x0a },
203         { 0x69, 0x09 },
204 };
205
206 static int s921_i2c_writereg(struct s921_state *state,
207                              u8 i2c_addr, int reg, int data)
208 {
209         u8 buf[] = { reg, data };
210         struct i2c_msg msg = {
211                 .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
212         };
213         int rc;
214
215         rc = i2c_transfer(state->i2c, &msg, 1);
216         if (rc != 1) {
217                 printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
218                          " data == 0x%02x)\n", __func__, rc, reg, data);
219                 return rc;
220         }
221
222         return 0;
223 }
224
225 static int s921_i2c_writeregdata(struct s921_state *state, u8 i2c_addr,
226                                  struct regdata *rd, int size)
227 {
228         int i, rc;
229
230         for (i = 0; i < size; i++) {
231                 rc = s921_i2c_writereg(state, i2c_addr, rd[i].reg, rd[i].data);
232                 if (rc < 0)
233                         return rc;
234         }
235         return 0;
236 }
237
238 static int s921_i2c_readreg(struct s921_state *state, u8 i2c_addr, u8 reg)
239 {
240         u8 val;
241         int rc;
242         struct i2c_msg msg[] = {
243                 { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
244                 { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
245         };
246
247         rc = i2c_transfer(state->i2c, msg, 2);
248
249         if (rc != 2) {
250                 rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
251                 return rc;
252         }
253
254         return val;
255 }
256
257 #define s921_readreg(state, reg) \
258         s921_i2c_readreg(state, state->config->demod_address, reg)
259 #define s921_writereg(state, reg, val) \
260         s921_i2c_writereg(state, state->config->demod_address, reg, val)
261 #define s921_writeregdata(state, regdata) \
262         s921_i2c_writeregdata(state, state->config->demod_address, \
263         regdata, ARRAY_SIZE(regdata))
264
265 static int s921_pll_tune(struct dvb_frontend *fe)
266 {
267         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
268         struct s921_state *state = fe->demodulator_priv;
269         int band, rc, i;
270         unsigned long f_offset;
271         u8 f_switch;
272         u64 offset;
273
274         dprintk("frequency=%i\n", p->frequency);
275
276         for (band = 0; band < ARRAY_SIZE(s921_bandselect); band++)
277                 if (p->frequency < s921_bandselect[band].freq_low)
278                         break;
279         band--;
280
281         if (band < 0) {
282                 rc("%s: frequency out of range\n", __func__);
283                 return -EINVAL;
284         }
285
286         f_switch = s921_bandselect[band].band_reg;
287
288         offset = ((u64)p->frequency) * 258;
289         do_div(offset, 6000000);
290         f_offset = ((unsigned long)offset) + 2321;
291
292         rc = s921_writeregdata(state, s921_prefreq);
293         if (rc < 0)
294                 return rc;
295
296         rc = s921_writereg(state, 0xf2, (f_offset >> 8) & 0xff);
297         if (rc < 0)
298                 return rc;
299
300         rc = s921_writereg(state, 0xf3, f_offset & 0xff);
301         if (rc < 0)
302                 return rc;
303
304         rc = s921_writereg(state, 0xf4, f_switch);
305         if (rc < 0)
306                 return rc;
307
308         rc = s921_writeregdata(state, s921_postfreq);
309         if (rc < 0)
310                 return rc;
311
312         for (i = 0 ; i < 6; i++) {
313                 rc = s921_readreg(state, 0x80);
314                 dprintk("status 0x80: %02x\n", rc);
315         }
316         rc = s921_writereg(state, 0x01, 0x40);
317         if (rc < 0)
318                 return rc;
319
320         rc = s921_readreg(state, 0x01);
321         dprintk("status 0x01: %02x\n", rc);
322
323         rc = s921_readreg(state, 0x80);
324         dprintk("status 0x80: %02x\n", rc);
325
326         rc = s921_readreg(state, 0x80);
327         dprintk("status 0x80: %02x\n", rc);
328
329         rc = s921_readreg(state, 0x32);
330         dprintk("status 0x32: %02x\n", rc);
331
332         dprintk("pll tune band=%d, pll=%d\n", f_switch, (int)f_offset);
333
334         return 0;
335 }
336
337 static int s921_initfe(struct dvb_frontend *fe)
338 {
339         struct s921_state *state = fe->demodulator_priv;
340         int rc;
341
342         dprintk("\n");
343
344         rc = s921_writeregdata(state, s921_init);
345         if (rc < 0)
346                 return rc;
347
348         return 0;
349 }
350
351 static int s921_read_status(struct dvb_frontend *fe, enum fe_status *status)
352 {
353         struct s921_state *state = fe->demodulator_priv;
354         int regstatus, rc;
355
356         *status = 0;
357
358         rc = s921_readreg(state, 0x81);
359         if (rc < 0)
360                 return rc;
361
362         regstatus = rc << 8;
363
364         rc = s921_readreg(state, 0x82);
365         if (rc < 0)
366                 return rc;
367
368         regstatus |= rc;
369
370         dprintk("status = %04x\n", regstatus);
371
372         /* Full Sync - We don't know what each bit means on regs 0x81/0x82 */
373         if ((regstatus & 0xff) == 0x40) {
374                 *status = FE_HAS_SIGNAL  |
375                           FE_HAS_CARRIER |
376                           FE_HAS_VITERBI |
377                           FE_HAS_SYNC    |
378                           FE_HAS_LOCK;
379         } else if (regstatus & 0x40) {
380                 /* This is close to Full Sync, but not enough to get useful info */
381                 *status = FE_HAS_SIGNAL  |
382                           FE_HAS_CARRIER |
383                           FE_HAS_VITERBI |
384                           FE_HAS_SYNC;
385         }
386
387         return 0;
388 }
389
390 static int s921_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
391 {
392         enum fe_status  status;
393         struct s921_state *state = fe->demodulator_priv;
394         int rc;
395
396         /* FIXME: Use the proper register for it... 0x80? */
397         rc = s921_read_status(fe, &status);
398         if (rc < 0)
399                 return rc;
400
401         *strength = (status & FE_HAS_LOCK) ? 0xffff : 0;
402
403         dprintk("strength = 0x%04x\n", *strength);
404
405         rc = s921_readreg(state, 0x01);
406         dprintk("status 0x01: %02x\n", rc);
407
408         rc = s921_readreg(state, 0x80);
409         dprintk("status 0x80: %02x\n", rc);
410
411         rc = s921_readreg(state, 0x32);
412         dprintk("status 0x32: %02x\n", rc);
413
414         return 0;
415 }
416
417 static int s921_set_frontend(struct dvb_frontend *fe)
418 {
419         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
420         struct s921_state *state = fe->demodulator_priv;
421         int rc;
422
423         dprintk("\n");
424
425         /* FIXME: We don't know how to use non-auto mode */
426
427         rc = s921_pll_tune(fe);
428         if (rc < 0)
429                 return rc;
430
431         state->currentfreq = p->frequency;
432
433         return 0;
434 }
435
436 static int s921_get_frontend(struct dvb_frontend *fe)
437 {
438         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
439         struct s921_state *state = fe->demodulator_priv;
440
441         /* FIXME: Probably it is possible to get it from regs f1 and f2 */
442         p->frequency = state->currentfreq;
443         p->delivery_system = SYS_ISDBT;
444
445         return 0;
446 }
447
448 static int s921_tune(struct dvb_frontend *fe,
449                         bool re_tune,
450                         unsigned int mode_flags,
451                         unsigned int *delay,
452                         enum fe_status *status)
453 {
454         int rc = 0;
455
456         dprintk("\n");
457
458         if (re_tune)
459                 rc = s921_set_frontend(fe);
460
461         if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
462                 s921_read_status(fe, status);
463
464         return rc;
465 }
466
467 static int s921_get_algo(struct dvb_frontend *fe)
468 {
469         return DVBFE_ALGO_HW;
470 }
471
472 static void s921_release(struct dvb_frontend *fe)
473 {
474         struct s921_state *state = fe->demodulator_priv;
475
476         dprintk("\n");
477         kfree(state);
478 }
479
480 static struct dvb_frontend_ops s921_ops;
481
482 struct dvb_frontend *s921_attach(const struct s921_config *config,
483                                     struct i2c_adapter *i2c)
484 {
485         /* allocate memory for the internal state */
486         struct s921_state *state =
487                 kzalloc(sizeof(struct s921_state), GFP_KERNEL);
488
489         dprintk("\n");
490         if (!state) {
491                 rc("Unable to kzalloc\n");
492                 return NULL;
493         }
494
495         /* setup the state */
496         state->config = config;
497         state->i2c = i2c;
498
499         /* create dvb_frontend */
500         memcpy(&state->frontend.ops, &s921_ops,
501                 sizeof(struct dvb_frontend_ops));
502         state->frontend.demodulator_priv = state;
503
504         return &state->frontend;
505 }
506 EXPORT_SYMBOL(s921_attach);
507
508 static struct dvb_frontend_ops s921_ops = {
509         .delsys = { SYS_ISDBT },
510         /* Use dib8000 values per default */
511         .info = {
512                 .name = "Sharp S921",
513                 .frequency_min = 470000000,
514                 /*
515                  * Max should be 770MHz instead, according with Sharp docs,
516                  * but Leadership doc says it works up to 806 MHz. This is
517                  * required to get channel 69, used in Brazil
518                  */
519                 .frequency_max = 806000000,
520                 .frequency_tolerance = 0,
521                  .caps = FE_CAN_INVERSION_AUTO |
522                          FE_CAN_FEC_1_2  | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
523                          FE_CAN_FEC_5_6  | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
524                          FE_CAN_QPSK     | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
525                          FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
526                          FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
527                          FE_CAN_HIERARCHY_AUTO,
528         },
529
530         .release = s921_release,
531
532         .init = s921_initfe,
533         .set_frontend = s921_set_frontend,
534         .get_frontend = s921_get_frontend,
535         .read_status = s921_read_status,
536         .read_signal_strength = s921_read_signal_strength,
537         .tune = s921_tune,
538         .get_frontend_algo = s921_get_algo,
539 };
540
541 MODULE_DESCRIPTION("DVB Frontend module for Sharp S921 hardware");
542 MODULE_AUTHOR("Mauro Carvalho Chehab");
543 MODULE_AUTHOR("Douglas Landgraf <dougsland@redhat.com>");
544 MODULE_LICENSE("GPL");