[media] au8522: bug-fix: enable modulation AFTER tune (instead of before tuning)
[pandora-kernel.git] / drivers / media / dvb / frontends / au8522_dig.c
1 /*
2     Auvitek AU8522 QAM/8VSB demodulator driver
3
4     Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
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     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 */
21
22 #include <linux/kernel.h>
23 #include <linux/init.h>
24 #include <linux/module.h>
25 #include <linux/string.h>
26 #include <linux/delay.h>
27 #include "dvb_frontend.h"
28 #include "au8522.h"
29 #include "au8522_priv.h"
30
31 static int debug;
32
33 /* Despite the name "hybrid_tuner", the framework works just as well for
34    hybrid demodulators as well... */
35 static LIST_HEAD(hybrid_tuner_instance_list);
36 static DEFINE_MUTEX(au8522_list_mutex);
37
38 #define dprintk(arg...)\
39         do { if (debug)\
40                 printk(arg);\
41         } while (0)
42
43 /* 16 bit registers, 8 bit values */
44 int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
45 {
46         int ret;
47         u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
48
49         struct i2c_msg msg = { .addr = state->config->demod_address,
50                                .flags = 0, .buf = buf, .len = 3 };
51
52         ret = i2c_transfer(state->i2c, &msg, 1);
53
54         if (ret != 1)
55                 printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
56                        "ret == %i)\n", __func__, reg, data, ret);
57
58         return (ret != 1) ? -1 : 0;
59 }
60
61 u8 au8522_readreg(struct au8522_state *state, u16 reg)
62 {
63         int ret;
64         u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff };
65         u8 b1[] = { 0 };
66
67         struct i2c_msg msg[] = {
68                 { .addr = state->config->demod_address, .flags = 0,
69                   .buf = b0, .len = 2 },
70                 { .addr = state->config->demod_address, .flags = I2C_M_RD,
71                   .buf = b1, .len = 1 } };
72
73         ret = i2c_transfer(state->i2c, msg, 2);
74
75         if (ret != 2)
76                 printk(KERN_ERR "%s: readreg error (ret == %i)\n",
77                        __func__, ret);
78         return b1[0];
79 }
80
81 static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
82 {
83         struct au8522_state *state = fe->demodulator_priv;
84
85         dprintk("%s(%d)\n", __func__, enable);
86
87         if (state->operational_mode == AU8522_ANALOG_MODE) {
88                 /* We're being asked to manage the gate even though we're
89                    not in digital mode.  This can occur if we get switched
90                    over to analog mode before the dvb_frontend kernel thread
91                    has completely shutdown */
92                 return 0;
93         }
94
95         if (enable)
96                 return au8522_writereg(state, 0x106, 1);
97         else
98                 return au8522_writereg(state, 0x106, 0);
99 }
100
101 struct mse2snr_tab {
102         u16 val;
103         u16 data;
104 };
105
106 /* VSB SNR lookup table */
107 static struct mse2snr_tab vsb_mse2snr_tab[] = {
108         {   0, 270 },
109         {   2, 250 },
110         {   3, 240 },
111         {   5, 230 },
112         {   7, 220 },
113         {   9, 210 },
114         {  12, 200 },
115         {  13, 195 },
116         {  15, 190 },
117         {  17, 185 },
118         {  19, 180 },
119         {  21, 175 },
120         {  24, 170 },
121         {  27, 165 },
122         {  31, 160 },
123         {  32, 158 },
124         {  33, 156 },
125         {  36, 152 },
126         {  37, 150 },
127         {  39, 148 },
128         {  40, 146 },
129         {  41, 144 },
130         {  43, 142 },
131         {  44, 140 },
132         {  48, 135 },
133         {  50, 130 },
134         {  43, 142 },
135         {  53, 125 },
136         {  56, 120 },
137         { 256, 115 },
138 };
139
140 /* QAM64 SNR lookup table */
141 static struct mse2snr_tab qam64_mse2snr_tab[] = {
142         {  15,   0 },
143         {  16, 290 },
144         {  17, 288 },
145         {  18, 286 },
146         {  19, 284 },
147         {  20, 282 },
148         {  21, 281 },
149         {  22, 279 },
150         {  23, 277 },
151         {  24, 275 },
152         {  25, 273 },
153         {  26, 271 },
154         {  27, 269 },
155         {  28, 268 },
156         {  29, 266 },
157         {  30, 264 },
158         {  31, 262 },
159         {  32, 260 },
160         {  33, 259 },
161         {  34, 258 },
162         {  35, 256 },
163         {  36, 255 },
164         {  37, 254 },
165         {  38, 252 },
166         {  39, 251 },
167         {  40, 250 },
168         {  41, 249 },
169         {  42, 248 },
170         {  43, 246 },
171         {  44, 245 },
172         {  45, 244 },
173         {  46, 242 },
174         {  47, 241 },
175         {  48, 240 },
176         {  50, 239 },
177         {  51, 238 },
178         {  53, 237 },
179         {  54, 236 },
180         {  56, 235 },
181         {  57, 234 },
182         {  59, 233 },
183         {  60, 232 },
184         {  62, 231 },
185         {  63, 230 },
186         {  65, 229 },
187         {  67, 228 },
188         {  68, 227 },
189         {  70, 226 },
190         {  71, 225 },
191         {  73, 224 },
192         {  74, 223 },
193         {  76, 222 },
194         {  78, 221 },
195         {  80, 220 },
196         {  82, 219 },
197         {  85, 218 },
198         {  88, 217 },
199         {  90, 216 },
200         {  92, 215 },
201         {  93, 214 },
202         {  94, 212 },
203         {  95, 211 },
204         {  97, 210 },
205         {  99, 209 },
206         { 101, 208 },
207         { 102, 207 },
208         { 104, 206 },
209         { 107, 205 },
210         { 111, 204 },
211         { 114, 203 },
212         { 118, 202 },
213         { 122, 201 },
214         { 125, 200 },
215         { 128, 199 },
216         { 130, 198 },
217         { 132, 197 },
218         { 256, 190 },
219 };
220
221 /* QAM256 SNR lookup table */
222 static struct mse2snr_tab qam256_mse2snr_tab[] = {
223         {  16,   0 },
224         {  17, 400 },
225         {  18, 398 },
226         {  19, 396 },
227         {  20, 394 },
228         {  21, 392 },
229         {  22, 390 },
230         {  23, 388 },
231         {  24, 386 },
232         {  25, 384 },
233         {  26, 382 },
234         {  27, 380 },
235         {  28, 379 },
236         {  29, 378 },
237         {  30, 377 },
238         {  31, 376 },
239         {  32, 375 },
240         {  33, 374 },
241         {  34, 373 },
242         {  35, 372 },
243         {  36, 371 },
244         {  37, 370 },
245         {  38, 362 },
246         {  39, 354 },
247         {  40, 346 },
248         {  41, 338 },
249         {  42, 330 },
250         {  43, 328 },
251         {  44, 326 },
252         {  45, 324 },
253         {  46, 322 },
254         {  47, 320 },
255         {  48, 319 },
256         {  49, 318 },
257         {  50, 317 },
258         {  51, 316 },
259         {  52, 315 },
260         {  53, 314 },
261         {  54, 313 },
262         {  55, 312 },
263         {  56, 311 },
264         {  57, 310 },
265         {  58, 308 },
266         {  59, 306 },
267         {  60, 304 },
268         {  61, 302 },
269         {  62, 300 },
270         {  63, 298 },
271         {  65, 295 },
272         {  68, 294 },
273         {  70, 293 },
274         {  73, 292 },
275         {  76, 291 },
276         {  78, 290 },
277         {  79, 289 },
278         {  81, 288 },
279         {  82, 287 },
280         {  83, 286 },
281         {  84, 285 },
282         {  85, 284 },
283         {  86, 283 },
284         {  88, 282 },
285         {  89, 281 },
286         { 256, 280 },
287 };
288
289 static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse,
290                                  u16 *snr)
291 {
292         int i, ret = -EINVAL;
293         dprintk("%s()\n", __func__);
294
295         for (i = 0; i < sz; i++) {
296                 if (mse < tab[i].val) {
297                         *snr = tab[i].data;
298                         ret = 0;
299                         break;
300                 }
301         }
302         dprintk("%s() snr=%d\n", __func__, *snr);
303         return ret;
304 }
305
306 static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq)
307 {
308         struct au8522_state *state = fe->demodulator_priv;
309         u8 r0b5, r0b6, r0b7;
310         char *ifmhz;
311
312         switch (if_freq) {
313         case AU8522_IF_3_25MHZ:
314                 ifmhz = "3.25";
315                 r0b5 = 0x00;
316                 r0b6 = 0x3d;
317                 r0b7 = 0xa0;
318                 break;
319         case AU8522_IF_4MHZ:
320                 ifmhz = "4.00";
321                 r0b5 = 0x00;
322                 r0b6 = 0x4b;
323                 r0b7 = 0xd9;
324                 break;
325         case AU8522_IF_6MHZ:
326                 ifmhz = "6.00";
327                 r0b5 = 0xfb;
328                 r0b6 = 0x8e;
329                 r0b7 = 0x39;
330                 break;
331         default:
332                 dprintk("%s() IF Frequency not supported\n", __func__);
333                 return -EINVAL;
334         }
335         dprintk("%s() %s MHz\n", __func__, ifmhz);
336         au8522_writereg(state, 0x80b5, r0b5);
337         au8522_writereg(state, 0x80b6, r0b6);
338         au8522_writereg(state, 0x80b7, r0b7);
339
340         return 0;
341 }
342
343 /* VSB Modulation table */
344 static struct {
345         u16 reg;
346         u16 data;
347 } VSB_mod_tab[] = {
348         { 0x8090, 0x84 },
349         { 0x4092, 0x11 },
350         { 0x2005, 0x00 },
351         { 0x8091, 0x80 },
352         { 0x80a3, 0x0c },
353         { 0x80a4, 0xe8 },
354         { 0x8081, 0xc4 },
355         { 0x80a5, 0x40 },
356         { 0x80a7, 0x40 },
357         { 0x80a6, 0x67 },
358         { 0x8262, 0x20 },
359         { 0x821c, 0x30 },
360         { 0x80d8, 0x1a },
361         { 0x8227, 0xa0 },
362         { 0x8121, 0xff },
363         { 0x80a8, 0xf0 },
364         { 0x80a9, 0x05 },
365         { 0x80aa, 0x77 },
366         { 0x80ab, 0xf0 },
367         { 0x80ac, 0x05 },
368         { 0x80ad, 0x77 },
369         { 0x80ae, 0x41 },
370         { 0x80af, 0x66 },
371         { 0x821b, 0xcc },
372         { 0x821d, 0x80 },
373         { 0x80a4, 0xe8 },
374         { 0x8231, 0x13 },
375 };
376
377 /* QAM64 Modulation table */
378 static struct {
379         u16 reg;
380         u16 data;
381 } QAM64_mod_tab[] = {
382         { 0x00a3, 0x09 },
383         { 0x00a4, 0x00 },
384         { 0x0081, 0xc4 },
385         { 0x00a5, 0x40 },
386         { 0x00aa, 0x77 },
387         { 0x00ad, 0x77 },
388         { 0x00a6, 0x67 },
389         { 0x0262, 0x20 },
390         { 0x021c, 0x30 },
391         { 0x00b8, 0x3e },
392         { 0x00b9, 0xf0 },
393         { 0x00ba, 0x01 },
394         { 0x00bb, 0x18 },
395         { 0x00bc, 0x50 },
396         { 0x00bd, 0x00 },
397         { 0x00be, 0xea },
398         { 0x00bf, 0xef },
399         { 0x00c0, 0xfc },
400         { 0x00c1, 0xbd },
401         { 0x00c2, 0x1f },
402         { 0x00c3, 0xfc },
403         { 0x00c4, 0xdd },
404         { 0x00c5, 0xaf },
405         { 0x00c6, 0x00 },
406         { 0x00c7, 0x38 },
407         { 0x00c8, 0x30 },
408         { 0x00c9, 0x05 },
409         { 0x00ca, 0x4a },
410         { 0x00cb, 0xd0 },
411         { 0x00cc, 0x01 },
412         { 0x00cd, 0xd9 },
413         { 0x00ce, 0x6f },
414         { 0x00cf, 0xf9 },
415         { 0x00d0, 0x70 },
416         { 0x00d1, 0xdf },
417         { 0x00d2, 0xf7 },
418         { 0x00d3, 0xc2 },
419         { 0x00d4, 0xdf },
420         { 0x00d5, 0x02 },
421         { 0x00d6, 0x9a },
422         { 0x00d7, 0xd0 },
423         { 0x0250, 0x0d },
424         { 0x0251, 0xcd },
425         { 0x0252, 0xe0 },
426         { 0x0253, 0x05 },
427         { 0x0254, 0xa7 },
428         { 0x0255, 0xff },
429         { 0x0256, 0xed },
430         { 0x0257, 0x5b },
431         { 0x0258, 0xae },
432         { 0x0259, 0xe6 },
433         { 0x025a, 0x3d },
434         { 0x025b, 0x0f },
435         { 0x025c, 0x0d },
436         { 0x025d, 0xea },
437         { 0x025e, 0xf2 },
438         { 0x025f, 0x51 },
439         { 0x0260, 0xf5 },
440         { 0x0261, 0x06 },
441         { 0x021a, 0x00 },
442         { 0x0546, 0x40 },
443         { 0x0210, 0xc7 },
444         { 0x0211, 0xaa },
445         { 0x0212, 0xab },
446         { 0x0213, 0x02 },
447         { 0x0502, 0x00 },
448         { 0x0121, 0x04 },
449         { 0x0122, 0x04 },
450         { 0x052e, 0x10 },
451         { 0x00a4, 0xca },
452         { 0x00a7, 0x40 },
453         { 0x0526, 0x01 },
454 };
455
456 /* QAM256 Modulation table */
457 static struct {
458         u16 reg;
459         u16 data;
460 } QAM256_mod_tab[] = {
461         { 0x80a3, 0x09 },
462         { 0x80a4, 0x00 },
463         { 0x8081, 0xc4 },
464         { 0x80a5, 0x40 },
465         { 0x80aa, 0x77 },
466         { 0x80ad, 0x77 },
467         { 0x80a6, 0x67 },
468         { 0x8262, 0x20 },
469         { 0x821c, 0x30 },
470         { 0x80b8, 0x3e },
471         { 0x80b9, 0xf0 },
472         { 0x80ba, 0x01 },
473         { 0x80bb, 0x18 },
474         { 0x80bc, 0x50 },
475         { 0x80bd, 0x00 },
476         { 0x80be, 0xea },
477         { 0x80bf, 0xef },
478         { 0x80c0, 0xfc },
479         { 0x80c1, 0xbd },
480         { 0x80c2, 0x1f },
481         { 0x80c3, 0xfc },
482         { 0x80c4, 0xdd },
483         { 0x80c5, 0xaf },
484         { 0x80c6, 0x00 },
485         { 0x80c7, 0x38 },
486         { 0x80c8, 0x30 },
487         { 0x80c9, 0x05 },
488         { 0x80ca, 0x4a },
489         { 0x80cb, 0xd0 },
490         { 0x80cc, 0x01 },
491         { 0x80cd, 0xd9 },
492         { 0x80ce, 0x6f },
493         { 0x80cf, 0xf9 },
494         { 0x80d0, 0x70 },
495         { 0x80d1, 0xdf },
496         { 0x80d2, 0xf7 },
497         { 0x80d3, 0xc2 },
498         { 0x80d4, 0xdf },
499         { 0x80d5, 0x02 },
500         { 0x80d6, 0x9a },
501         { 0x80d7, 0xd0 },
502         { 0x8250, 0x0d },
503         { 0x8251, 0xcd },
504         { 0x8252, 0xe0 },
505         { 0x8253, 0x05 },
506         { 0x8254, 0xa7 },
507         { 0x8255, 0xff },
508         { 0x8256, 0xed },
509         { 0x8257, 0x5b },
510         { 0x8258, 0xae },
511         { 0x8259, 0xe6 },
512         { 0x825a, 0x3d },
513         { 0x825b, 0x0f },
514         { 0x825c, 0x0d },
515         { 0x825d, 0xea },
516         { 0x825e, 0xf2 },
517         { 0x825f, 0x51 },
518         { 0x8260, 0xf5 },
519         { 0x8261, 0x06 },
520         { 0x821a, 0x00 },
521         { 0x8546, 0x40 },
522         { 0x8210, 0x26 },
523         { 0x8211, 0xf6 },
524         { 0x8212, 0x84 },
525         { 0x8213, 0x02 },
526         { 0x8502, 0x01 },
527         { 0x8121, 0x04 },
528         { 0x8122, 0x04 },
529         { 0x852e, 0x10 },
530         { 0x80a4, 0xca },
531         { 0x80a7, 0x40 },
532         { 0x8526, 0x01 },
533 };
534
535 static int au8522_enable_modulation(struct dvb_frontend *fe,
536                                     fe_modulation_t m)
537 {
538         struct au8522_state *state = fe->demodulator_priv;
539         int i;
540
541         dprintk("%s(0x%08x)\n", __func__, m);
542
543         switch (m) {
544         case VSB_8:
545                 dprintk("%s() VSB_8\n", __func__);
546                 for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++)
547                         au8522_writereg(state,
548                                 VSB_mod_tab[i].reg,
549                                 VSB_mod_tab[i].data);
550                 au8522_set_if(fe, state->config->vsb_if);
551                 break;
552         case QAM_64:
553                 dprintk("%s() QAM 64\n", __func__);
554                 for (i = 0; i < ARRAY_SIZE(QAM64_mod_tab); i++)
555                         au8522_writereg(state,
556                                 QAM64_mod_tab[i].reg,
557                                 QAM64_mod_tab[i].data);
558                 au8522_set_if(fe, state->config->qam_if);
559                 break;
560         case QAM_256:
561                 dprintk("%s() QAM 256\n", __func__);
562                 for (i = 0; i < ARRAY_SIZE(QAM256_mod_tab); i++)
563                         au8522_writereg(state,
564                                 QAM256_mod_tab[i].reg,
565                                 QAM256_mod_tab[i].data);
566                 au8522_set_if(fe, state->config->qam_if);
567                 break;
568         default:
569                 dprintk("%s() Invalid modulation\n", __func__);
570                 return -EINVAL;
571         }
572
573         state->current_modulation = m;
574
575         return 0;
576 }
577
578 /* Talk to the demod, set the FEC, GUARD, QAM settings etc */
579 static int au8522_set_frontend(struct dvb_frontend *fe)
580 {
581         struct dtv_frontend_properties *c = &fe->dtv_property_cache;
582         struct au8522_state *state = fe->demodulator_priv;
583         int ret = -EINVAL;
584
585         dprintk("%s(frequency=%d)\n", __func__, c->frequency);
586
587         if ((state->current_frequency == c->frequency) &&
588             (state->current_modulation == c->modulation))
589                 return 0;
590
591         if (fe->ops.tuner_ops.set_params) {
592                 if (fe->ops.i2c_gate_ctrl)
593                         fe->ops.i2c_gate_ctrl(fe, 1);
594                 ret = fe->ops.tuner_ops.set_params(fe);
595                 if (fe->ops.i2c_gate_ctrl)
596                         fe->ops.i2c_gate_ctrl(fe, 0);
597         }
598
599         if (ret < 0)
600                 return ret;
601
602         /* Allow the tuner to settle */
603         msleep(100);
604
605         au8522_enable_modulation(fe, c->modulation);
606
607         state->current_frequency = c->frequency;
608
609         return 0;
610 }
611
612 /* Reset the demod hardware and reset all of the configuration registers
613    to a default state. */
614 int au8522_init(struct dvb_frontend *fe)
615 {
616         struct au8522_state *state = fe->demodulator_priv;
617         dprintk("%s()\n", __func__);
618
619         state->operational_mode = AU8522_DIGITAL_MODE;
620
621         /* Clear out any state associated with the digital side of the
622            chip, so that when it gets powered back up it won't think
623            that it is already tuned */
624         state->current_frequency = 0;
625
626         au8522_writereg(state, 0xa4, 1 << 5);
627
628         au8522_i2c_gate_ctrl(fe, 1);
629
630         return 0;
631 }
632
633 static int au8522_led_gpio_enable(struct au8522_state *state, int onoff)
634 {
635         struct au8522_led_config *led_config = state->config->led_cfg;
636         u8 val;
637
638         /* bail out if we can't control an LED */
639         if (!led_config || !led_config->gpio_output ||
640             !led_config->gpio_output_enable || !led_config->gpio_output_disable)
641                 return 0;
642
643         val = au8522_readreg(state, 0x4000 |
644                              (led_config->gpio_output & ~0xc000));
645         if (onoff) {
646                 /* enable GPIO output */
647                 val &= ~((led_config->gpio_output_enable >> 8) & 0xff);
648                 val |=  (led_config->gpio_output_enable & 0xff);
649         } else {
650                 /* disable GPIO output */
651                 val &= ~((led_config->gpio_output_disable >> 8) & 0xff);
652                 val |=  (led_config->gpio_output_disable & 0xff);
653         }
654         return au8522_writereg(state, 0x8000 |
655                                (led_config->gpio_output & ~0xc000), val);
656 }
657
658 /* led = 0 | off
659  * led = 1 | signal ok
660  * led = 2 | signal strong
661  * led < 0 | only light led if leds are currently off
662  */
663 static int au8522_led_ctrl(struct au8522_state *state, int led)
664 {
665         struct au8522_led_config *led_config = state->config->led_cfg;
666         int i, ret = 0;
667
668         /* bail out if we can't control an LED */
669         if (!led_config || !led_config->gpio_leds ||
670             !led_config->num_led_states || !led_config->led_states)
671                 return 0;
672
673         if (led < 0) {
674                 /* if LED is already lit, then leave it as-is */
675                 if (state->led_state)
676                         return 0;
677                 else
678                         led *= -1;
679         }
680
681         /* toggle LED if changing state */
682         if (state->led_state != led) {
683                 u8 val;
684
685                 dprintk("%s: %d\n", __func__, led);
686
687                 au8522_led_gpio_enable(state, 1);
688
689                 val = au8522_readreg(state, 0x4000 |
690                                      (led_config->gpio_leds & ~0xc000));
691
692                 /* start with all leds off */
693                 for (i = 0; i < led_config->num_led_states; i++)
694                         val &= ~led_config->led_states[i];
695
696                 /* set selected LED state */
697                 if (led < led_config->num_led_states)
698                         val |= led_config->led_states[led];
699                 else if (led_config->num_led_states)
700                         val |=
701                         led_config->led_states[led_config->num_led_states - 1];
702
703                 ret = au8522_writereg(state, 0x8000 |
704                                       (led_config->gpio_leds & ~0xc000), val);
705                 if (ret < 0)
706                         return ret;
707
708                 state->led_state = led;
709
710                 if (led == 0)
711                         au8522_led_gpio_enable(state, 0);
712         }
713
714         return 0;
715 }
716
717 int au8522_sleep(struct dvb_frontend *fe)
718 {
719         struct au8522_state *state = fe->demodulator_priv;
720         dprintk("%s()\n", __func__);
721
722         /* Only power down if the digital side is currently using the chip */
723         if (state->operational_mode == AU8522_ANALOG_MODE) {
724                 /* We're not in one of the expected power modes, which means
725                    that the DVB thread is probably telling us to go to sleep
726                    even though the analog frontend has already started using
727                    the chip.  So ignore the request */
728                 return 0;
729         }
730
731         /* turn off led */
732         au8522_led_ctrl(state, 0);
733
734         /* Power down the chip */
735         au8522_writereg(state, 0xa4, 1 << 5);
736
737         state->current_frequency = 0;
738
739         return 0;
740 }
741
742 static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
743 {
744         struct au8522_state *state = fe->demodulator_priv;
745         u8 reg;
746         u32 tuner_status = 0;
747
748         *status = 0;
749
750         if (state->current_modulation == VSB_8) {
751                 dprintk("%s() Checking VSB_8\n", __func__);
752                 reg = au8522_readreg(state, 0x4088);
753                 if ((reg & 0x03) == 0x03)
754                         *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
755         } else {
756                 dprintk("%s() Checking QAM\n", __func__);
757                 reg = au8522_readreg(state, 0x4541);
758                 if (reg & 0x80)
759                         *status |= FE_HAS_VITERBI;
760                 if (reg & 0x20)
761                         *status |= FE_HAS_LOCK | FE_HAS_SYNC;
762         }
763
764         switch (state->config->status_mode) {
765         case AU8522_DEMODLOCKING:
766                 dprintk("%s() DEMODLOCKING\n", __func__);
767                 if (*status & FE_HAS_VITERBI)
768                         *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
769                 break;
770         case AU8522_TUNERLOCKING:
771                 /* Get the tuner status */
772                 dprintk("%s() TUNERLOCKING\n", __func__);
773                 if (fe->ops.tuner_ops.get_status) {
774                         if (fe->ops.i2c_gate_ctrl)
775                                 fe->ops.i2c_gate_ctrl(fe, 1);
776
777                         fe->ops.tuner_ops.get_status(fe, &tuner_status);
778
779                         if (fe->ops.i2c_gate_ctrl)
780                                 fe->ops.i2c_gate_ctrl(fe, 0);
781                 }
782                 if (tuner_status)
783                         *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
784                 break;
785         }
786         state->fe_status = *status;
787
788         if (*status & FE_HAS_LOCK)
789                 /* turn on LED, if it isn't on already */
790                 au8522_led_ctrl(state, -1);
791         else
792                 /* turn off LED */
793                 au8522_led_ctrl(state, 0);
794
795         dprintk("%s() status 0x%08x\n", __func__, *status);
796
797         return 0;
798 }
799
800 static int au8522_led_status(struct au8522_state *state, const u16 *snr)
801 {
802         struct au8522_led_config *led_config = state->config->led_cfg;
803         int led;
804         u16 strong;
805
806         /* bail out if we can't control an LED */
807         if (!led_config)
808                 return 0;
809
810         if (0 == (state->fe_status & FE_HAS_LOCK))
811                 return au8522_led_ctrl(state, 0);
812         else if (state->current_modulation == QAM_256)
813                 strong = led_config->qam256_strong;
814         else if (state->current_modulation == QAM_64)
815                 strong = led_config->qam64_strong;
816         else /* (state->current_modulation == VSB_8) */
817                 strong = led_config->vsb8_strong;
818
819         if (*snr >= strong)
820                 led = 2;
821         else
822                 led = 1;
823
824         if ((state->led_state) &&
825             (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10))
826                 /* snr didn't change enough to bother
827                  * changing the color of the led */
828                 return 0;
829
830         return au8522_led_ctrl(state, led);
831 }
832
833 static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
834 {
835         struct au8522_state *state = fe->demodulator_priv;
836         int ret = -EINVAL;
837
838         dprintk("%s()\n", __func__);
839
840         if (state->current_modulation == QAM_256)
841                 ret = au8522_mse2snr_lookup(qam256_mse2snr_tab,
842                                             ARRAY_SIZE(qam256_mse2snr_tab),
843                                             au8522_readreg(state, 0x4522),
844                                             snr);
845         else if (state->current_modulation == QAM_64)
846                 ret = au8522_mse2snr_lookup(qam64_mse2snr_tab,
847                                             ARRAY_SIZE(qam64_mse2snr_tab),
848                                             au8522_readreg(state, 0x4522),
849                                             snr);
850         else /* VSB_8 */
851                 ret = au8522_mse2snr_lookup(vsb_mse2snr_tab,
852                                             ARRAY_SIZE(vsb_mse2snr_tab),
853                                             au8522_readreg(state, 0x4311),
854                                             snr);
855
856         if (state->config->led_cfg)
857                 au8522_led_status(state, snr);
858
859         return ret;
860 }
861
862 static int au8522_read_signal_strength(struct dvb_frontend *fe,
863                                        u16 *signal_strength)
864 {
865         /* borrowed from lgdt330x.c
866          *
867          * Calculate strength from SNR up to 35dB
868          * Even though the SNR can go higher than 35dB,
869          * there is some comfort factor in having a range of
870          * strong signals that can show at 100%
871          */
872         u16 snr;
873         u32 tmp;
874         int ret = au8522_read_snr(fe, &snr);
875
876         *signal_strength = 0;
877
878         if (0 == ret) {
879                 /* The following calculation method was chosen
880                  * purely for the sake of code re-use from the
881                  * other demod drivers that use this method */
882
883                 /* Convert from SNR in dB * 10 to 8.24 fixed-point */
884                 tmp = (snr * ((1 << 24) / 10));
885
886                 /* Convert from 8.24 fixed-point to
887                  * scale the range 0 - 35*2^24 into 0 - 65535*/
888                 if (tmp >= 8960 * 0x10000)
889                         *signal_strength = 0xffff;
890                 else
891                         *signal_strength = tmp / 8960;
892         }
893
894         return ret;
895 }
896
897 static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
898 {
899         struct au8522_state *state = fe->demodulator_priv;
900
901         if (state->current_modulation == VSB_8)
902                 *ucblocks = au8522_readreg(state, 0x4087);
903         else
904                 *ucblocks = au8522_readreg(state, 0x4543);
905
906         return 0;
907 }
908
909 static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber)
910 {
911         return au8522_read_ucblocks(fe, ber);
912 }
913
914 static int au8522_get_frontend(struct dvb_frontend *fe)
915 {
916         struct dtv_frontend_properties *c = &fe->dtv_property_cache;
917         struct au8522_state *state = fe->demodulator_priv;
918
919         c->frequency = state->current_frequency;
920         c->modulation = state->current_modulation;
921
922         return 0;
923 }
924
925 static int au8522_get_tune_settings(struct dvb_frontend *fe,
926                                     struct dvb_frontend_tune_settings *tune)
927 {
928         tune->min_delay_ms = 1000;
929         return 0;
930 }
931
932 static struct dvb_frontend_ops au8522_ops;
933
934 int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
935                      u8 client_address)
936 {
937         int ret;
938
939         mutex_lock(&au8522_list_mutex);
940         ret = hybrid_tuner_request_state(struct au8522_state, (*state),
941                                          hybrid_tuner_instance_list,
942                                          i2c, client_address, "au8522");
943         mutex_unlock(&au8522_list_mutex);
944
945         return ret;
946 }
947
948 void au8522_release_state(struct au8522_state *state)
949 {
950         mutex_lock(&au8522_list_mutex);
951         if (state != NULL)
952                 hybrid_tuner_release_state(state);
953         mutex_unlock(&au8522_list_mutex);
954 }
955
956
957 static void au8522_release(struct dvb_frontend *fe)
958 {
959         struct au8522_state *state = fe->demodulator_priv;
960         au8522_release_state(state);
961 }
962
963 struct dvb_frontend *au8522_attach(const struct au8522_config *config,
964                                    struct i2c_adapter *i2c)
965 {
966         struct au8522_state *state = NULL;
967         int instance;
968
969         /* allocate memory for the internal state */
970         instance = au8522_get_state(&state, i2c, config->demod_address);
971         switch (instance) {
972         case 0:
973                 dprintk("%s state allocation failed\n", __func__);
974                 break;
975         case 1:
976                 /* new demod instance */
977                 dprintk("%s using new instance\n", __func__);
978                 break;
979         default:
980                 /* existing demod instance */
981                 dprintk("%s using existing instance\n", __func__);
982                 break;
983         }
984
985         /* setup the state */
986         state->config = config;
987         state->i2c = i2c;
988         state->operational_mode = AU8522_DIGITAL_MODE;
989
990         /* create dvb_frontend */
991         memcpy(&state->frontend.ops, &au8522_ops,
992                sizeof(struct dvb_frontend_ops));
993         state->frontend.demodulator_priv = state;
994
995         if (au8522_init(&state->frontend) != 0) {
996                 printk(KERN_ERR "%s: Failed to initialize correctly\n",
997                         __func__);
998                 goto error;
999         }
1000
1001         /* Note: Leaving the I2C gate open here. */
1002         au8522_i2c_gate_ctrl(&state->frontend, 1);
1003
1004         return &state->frontend;
1005
1006 error:
1007         au8522_release_state(state);
1008         return NULL;
1009 }
1010 EXPORT_SYMBOL(au8522_attach);
1011
1012 static struct dvb_frontend_ops au8522_ops = {
1013         .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
1014         .info = {
1015                 .name                   = "Auvitek AU8522 QAM/8VSB Frontend",
1016                 .frequency_min          = 54000000,
1017                 .frequency_max          = 858000000,
1018                 .frequency_stepsize     = 62500,
1019                 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
1020         },
1021
1022         .init                 = au8522_init,
1023         .sleep                = au8522_sleep,
1024         .i2c_gate_ctrl        = au8522_i2c_gate_ctrl,
1025         .set_frontend         = au8522_set_frontend,
1026         .get_frontend         = au8522_get_frontend,
1027         .get_tune_settings    = au8522_get_tune_settings,
1028         .read_status          = au8522_read_status,
1029         .read_ber             = au8522_read_ber,
1030         .read_signal_strength = au8522_read_signal_strength,
1031         .read_snr             = au8522_read_snr,
1032         .read_ucblocks        = au8522_read_ucblocks,
1033         .release              = au8522_release,
1034 };
1035
1036 module_param(debug, int, 0644);
1037 MODULE_PARM_DESC(debug, "Enable verbose debug messages");
1038
1039 MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver");
1040 MODULE_AUTHOR("Steven Toth");
1041 MODULE_LICENSE("GPL");