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 */
au8522_writereg(struct au8522_state * state,u16 reg,u8 data)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 
au8522_readreg(struct au8522_state * state,u16 reg)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 
au8522_i2c_gate_ctrl(struct dvb_frontend * fe,int enable)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 
au8522_mse2snr_lookup(struct mse2snr_tab * tab,int sz,int mse,u16 * snr)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 
au8522_set_if(struct dvb_frontend * fe,enum au8522_if_freq if_freq)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 
au8522_enable_modulation(struct dvb_frontend * fe,fe_modulation_t m)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 */
au8522_set_frontend(struct dvb_frontend * fe)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. */
au8522_init(struct dvb_frontend * fe)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 
au8522_led_gpio_enable(struct au8522_state * state,int onoff)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  */
au8522_led_ctrl(struct au8522_state * state,int led)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 
au8522_sleep(struct dvb_frontend * fe)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 
au8522_read_status(struct dvb_frontend * fe,fe_status_t * status)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 
au8522_led_status(struct au8522_state * state,const u16 * snr)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 
au8522_read_snr(struct dvb_frontend * fe,u16 * snr)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 
au8522_read_signal_strength(struct dvb_frontend * fe,u16 * signal_strength)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 
au8522_read_ucblocks(struct dvb_frontend * fe,u32 * ucblocks)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 
au8522_read_ber(struct dvb_frontend * fe,u32 * ber)909 static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber)
910 {
911 	return au8522_read_ucblocks(fe, ber);
912 }
913 
au8522_get_frontend(struct dvb_frontend * fe)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 
au8522_get_tune_settings(struct dvb_frontend * fe,struct dvb_frontend_tune_settings * tune)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 
au8522_get_state(struct au8522_state ** state,struct i2c_adapter * i2c,u8 client_address)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 
au8522_release_state(struct au8522_state * state)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 
au8522_release(struct dvb_frontend * fe)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 
au8522_attach(const struct au8522_config * config,struct i2c_adapter * i2c)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");
1042