aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/au8522.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends/au8522.c')
-rw-r--r--drivers/media/dvb/frontends/au8522.c511
1 files changed, 382 insertions, 129 deletions
diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c
index d445cf1e02be..fa3e6abdfa6e 100644
--- a/drivers/media/dvb/frontends/au8522.c
+++ b/drivers/media/dvb/frontends/au8522.c
@@ -96,129 +96,388 @@ static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
96 return au8522_writereg(state, 0x106, 0); 96 return au8522_writereg(state, 0x106, 0);
97} 97}
98 98
99/* VSB SNR lookup table */
100static struct {
101 u16 val;
102 u16 data;
103} vsb_mse2snr_tab[] = {
104 { 0, 270 },
105 { 2, 250 },
106 { 3, 240 },
107 { 5, 230 },
108 { 7, 220 },
109 { 9, 210 },
110 { 12, 200 },
111 { 13, 195 },
112 { 15, 190 },
113 { 17, 185 },
114 { 19, 180 },
115 { 21, 175 },
116 { 24, 170 },
117 { 27, 165 },
118 { 31, 160 },
119 { 32, 158 },
120 { 33, 156 },
121 { 36, 152 },
122 { 37, 150 },
123 { 39, 148 },
124 { 40, 146 },
125 { 41, 144 },
126 { 43, 142 },
127 { 44, 140 },
128 { 48, 135 },
129 { 50, 130 },
130 { 43, 142 },
131 { 53, 125 },
132 { 56, 120 },
133 { 256, 115 },
134};
135
136/* QAM64 SNR lookup table */
137static struct {
138 u16 val;
139 u16 data;
140} qam64_mse2snr_tab[] = {
141 { 15, 0 },
142 { 16, 290 },
143 { 17, 288 },
144 { 18, 286 },
145 { 19, 284 },
146 { 20, 282 },
147 { 21, 281 },
148 { 22, 279 },
149 { 23, 277 },
150 { 24, 275 },
151 { 25, 273 },
152 { 26, 271 },
153 { 27, 269 },
154 { 28, 268 },
155 { 29, 266 },
156 { 30, 264 },
157 { 31, 262 },
158 { 32, 260 },
159 { 33, 259 },
160 { 34, 258 },
161 { 35, 256 },
162 { 36, 255 },
163 { 37, 254 },
164 { 38, 252 },
165 { 39, 251 },
166 { 40, 250 },
167 { 41, 249 },
168 { 42, 248 },
169 { 43, 246 },
170 { 44, 245 },
171 { 45, 244 },
172 { 46, 242 },
173 { 47, 241 },
174 { 48, 240 },
175 { 50, 239 },
176 { 51, 238 },
177 { 53, 237 },
178 { 54, 236 },
179 { 56, 235 },
180 { 57, 234 },
181 { 59, 233 },
182 { 60, 232 },
183 { 62, 231 },
184 { 63, 230 },
185 { 65, 229 },
186 { 67, 228 },
187 { 68, 227 },
188 { 70, 226 },
189 { 71, 225 },
190 { 73, 224 },
191 { 74, 223 },
192 { 76, 222 },
193 { 78, 221 },
194 { 80, 220 },
195 { 82, 219 },
196 { 85, 218 },
197 { 88, 217 },
198 { 90, 216 },
199 { 92, 215 },
200 { 93, 214 },
201 { 94, 212 },
202 { 95, 211 },
203 { 97, 210 },
204 { 99, 209 },
205 { 101, 208 },
206 { 102, 207 },
207 { 104, 206 },
208 { 107, 205 },
209 { 111, 204 },
210 { 114, 203 },
211 { 118, 202 },
212 { 122, 201 },
213 { 125, 200 },
214 { 128, 199 },
215 { 130, 198 },
216 { 132, 197 },
217 { 256, 190 },
218};
219
220/* QAM256 SNR lookup table */
221static struct {
222 u16 val;
223 u16 data;
224} qam256_mse2snr_tab[] = {
225 { 16, 0 },
226 { 17, 400 },
227 { 18, 398 },
228 { 19, 396 },
229 { 20, 394 },
230 { 21, 392 },
231 { 22, 390 },
232 { 23, 388 },
233 { 24, 386 },
234 { 25, 384 },
235 { 26, 382 },
236 { 27, 380 },
237 { 28, 379 },
238 { 29, 378 },
239 { 30, 377 },
240 { 31, 376 },
241 { 32, 375 },
242 { 33, 374 },
243 { 34, 373 },
244 { 35, 372 },
245 { 36, 371 },
246 { 37, 370 },
247 { 38, 362 },
248 { 39, 354 },
249 { 40, 346 },
250 { 41, 338 },
251 { 42, 330 },
252 { 43, 328 },
253 { 44, 326 },
254 { 45, 324 },
255 { 46, 322 },
256 { 47, 320 },
257 { 48, 319 },
258 { 49, 318 },
259 { 50, 317 },
260 { 51, 316 },
261 { 52, 315 },
262 { 53, 314 },
263 { 54, 313 },
264 { 55, 312 },
265 { 56, 311 },
266 { 57, 310 },
267 { 58, 308 },
268 { 59, 306 },
269 { 60, 304 },
270 { 61, 302 },
271 { 62, 300 },
272 { 63, 298 },
273 { 65, 295 },
274 { 68, 294 },
275 { 70, 293 },
276 { 73, 292 },
277 { 76, 291 },
278 { 78, 290 },
279 { 79, 289 },
280 { 81, 288 },
281 { 82, 287 },
282 { 83, 286 },
283 { 84, 285 },
284 { 85, 284 },
285 { 86, 283 },
286 { 88, 282 },
287 { 89, 281 },
288 { 256, 280 },
289};
290
291static int au8522_vsb_mse2snr_lookup(int mse, u16 *snr)
292{
293 int i, ret = -EINVAL;
294 dprintk("%s()\n", __func__);
295
296 for (i = 0; i < ARRAY_SIZE(vsb_mse2snr_tab); i++) {
297 if (mse < vsb_mse2snr_tab[i].val) {
298 *snr = vsb_mse2snr_tab[i].data;
299 ret = 0;
300 break;
301 }
302 }
303 dprintk("%s() snr=%d\n", __func__, *snr);
304 return ret;
305}
306
307static int au8522_qam64_mse2snr_lookup(int mse, u16 *snr)
308{
309 int i, ret = -EINVAL;
310 dprintk("%s()\n", __func__);
311
312 for (i = 0; i < ARRAY_SIZE(qam64_mse2snr_tab); i++) {
313 if (mse < qam64_mse2snr_tab[i].val) {
314 *snr = qam64_mse2snr_tab[i].data;
315 ret = 0;
316 break;
317 }
318 }
319 dprintk("%s() snr=%d\n", __func__, *snr);
320 return ret;
321}
322
323static int au8522_qam256_mse2snr_lookup(int mse, u16 *snr)
324{
325 int i, ret = -EINVAL;
326 dprintk("%s()\n", __func__);
327
328 for (i = 0; i < ARRAY_SIZE(qam256_mse2snr_tab); i++) {
329 if (mse < qam256_mse2snr_tab[i].val) {
330 *snr = qam256_mse2snr_tab[i].data;
331 ret = 0;
332 break;
333 }
334 }
335 dprintk("%s() snr=%d\n", __func__, *snr);
336 return ret;
337}
338
339/* VSB Modulation table */
340static struct {
341 u16 reg;
342 u16 data;
343} VSB_mod_tab[] = {
344 { 0x8090, 0x84 },
345 { 0x4092, 0x11 },
346 { 0x2005, 0x00 },
347 { 0x8091, 0x80 },
348 { 0x80a3, 0x0c },
349 { 0x80a4, 0xe8 },
350 { 0x8081, 0xc4 },
351 { 0x80a5, 0x40 },
352 { 0x80a7, 0x40 },
353 { 0x80a6, 0x67 },
354 { 0x8262, 0x20 },
355 { 0x821c, 0x30 },
356 { 0x80d8, 0x1a },
357 { 0x8227, 0xa0 },
358 { 0x8121, 0xff },
359 { 0x80a8, 0xf0 },
360 { 0x80a9, 0x05 },
361 { 0x80aa, 0x77 },
362 { 0x80ab, 0xf0 },
363 { 0x80ac, 0x05 },
364 { 0x80ad, 0x77 },
365 { 0x80ae, 0x41 },
366 { 0x80af, 0x66 },
367 { 0x821b, 0xcc },
368 { 0x821d, 0x80 },
369 { 0x80b5, 0xfb },
370 { 0x80b6, 0x8e },
371 { 0x80b7, 0x39 },
372 { 0x80a4, 0xe8 },
373 { 0x8231, 0x13 },
374};
375
376/* QAM Modulation table */
377static struct {
378 u16 reg;
379 u16 data;
380} QAM_mod_tab[] = {
381 { 0x80a3, 0x09 },
382 { 0x80a4, 0x00 },
383 { 0x8081, 0xc4 },
384 { 0x80a5, 0x40 },
385 { 0x80b5, 0xfb },
386 { 0x80b6, 0x8e },
387 { 0x80b7, 0x39 },
388 { 0x80aa, 0x77 },
389 { 0x80ad, 0x77 },
390 { 0x80a6, 0x67 },
391 { 0x8262, 0x20 },
392 { 0x821c, 0x30 },
393 { 0x80b8, 0x3e },
394 { 0x80b9, 0xf0 },
395 { 0x80ba, 0x01 },
396 { 0x80bb, 0x18 },
397 { 0x80bc, 0x50 },
398 { 0x80bd, 0x00 },
399 { 0x80be, 0xea },
400 { 0x80bf, 0xef },
401 { 0x80c0, 0xfc },
402 { 0x80c1, 0xbd },
403 { 0x80c2, 0x1f },
404 { 0x80c3, 0xfc },
405 { 0x80c4, 0xdd },
406 { 0x80c5, 0xaf },
407 { 0x80c6, 0x00 },
408 { 0x80c7, 0x38 },
409 { 0x80c8, 0x30 },
410 { 0x80c9, 0x05 },
411 { 0x80ca, 0x4a },
412 { 0x80cb, 0xd0 },
413 { 0x80cc, 0x01 },
414 { 0x80cd, 0xd9 },
415 { 0x80ce, 0x6f },
416 { 0x80cf, 0xf9 },
417 { 0x80d0, 0x70 },
418 { 0x80d1, 0xdf },
419 { 0x80d2, 0xf7 },
420 { 0x80d3, 0xc2 },
421 { 0x80d4, 0xdf },
422 { 0x80d5, 0x02 },
423 { 0x80d6, 0x9a },
424 { 0x80d7, 0xd0 },
425 { 0x8250, 0x0d },
426 { 0x8251, 0xcd },
427 { 0x8252, 0xe0 },
428 { 0x8253, 0x05 },
429 { 0x8254, 0xa7 },
430 { 0x8255, 0xff },
431 { 0x8256, 0xed },
432 { 0x8257, 0x5b },
433 { 0x8258, 0xae },
434 { 0x8259, 0xe6 },
435 { 0x825a, 0x3d },
436 { 0x825b, 0x0f },
437 { 0x825c, 0x0d },
438 { 0x825d, 0xea },
439 { 0x825e, 0xf2 },
440 { 0x825f, 0x51 },
441 { 0x8260, 0xf5 },
442 { 0x8261, 0x06 },
443 { 0x821a, 0x00 },
444 { 0x8546, 0x40 },
445 { 0x8210, 0x26 },
446 { 0x8211, 0xf6 },
447 { 0x8212, 0x84 },
448 { 0x8213, 0x02 },
449 { 0x8502, 0x01 },
450 { 0x8121, 0x04 },
451 { 0x8122, 0x04 },
452 { 0x852e, 0x10 },
453 { 0x80a4, 0xca },
454 { 0x80a7, 0x40 },
455 { 0x8526, 0x01 },
456};
457
99static int au8522_enable_modulation(struct dvb_frontend *fe, 458static int au8522_enable_modulation(struct dvb_frontend *fe,
100 fe_modulation_t m) 459 fe_modulation_t m)
101{ 460{
102 struct au8522_state *state = fe->demodulator_priv; 461 struct au8522_state *state = fe->demodulator_priv;
462 int i;
103 463
104 dprintk("%s(0x%08x)\n", __func__, m); 464 dprintk("%s(0x%08x)\n", __func__, m);
105 465
106 switch(m) { 466 switch(m) {
107 case VSB_8: 467 case VSB_8:
108 dprintk("%s() VSB_8\n", __func__); 468 dprintk("%s() VSB_8\n", __func__);
109 469 for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++)
110 //au8522_writereg(state, 0x410b, 0x84); // Serial 470 au8522_writereg(state,
111 471 VSB_mod_tab[i].reg,
112 //au8522_writereg(state, 0x8090, 0x82); 472 VSB_mod_tab[i].data);
113 au8522_writereg(state, 0x8090, 0x84);
114 au8522_writereg(state, 0x4092, 0x11);
115 au8522_writereg(state, 0x2005, 0x00);
116 au8522_writereg(state, 0x8091, 0x80);
117
118 au8522_writereg(state, 0x80a3, 0x0c);
119 au8522_writereg(state, 0x80a4, 0xe8);
120 au8522_writereg(state, 0x8081, 0xc4);
121 au8522_writereg(state, 0x80a5, 0x40);
122 au8522_writereg(state, 0x80a7, 0x40);
123 au8522_writereg(state, 0x80a6, 0x67);
124 au8522_writereg(state, 0x8262, 0x20);
125 au8522_writereg(state, 0x821c, 0x30);
126 au8522_writereg(state, 0x80d8, 0x1a);
127 au8522_writereg(state, 0x8227, 0xa0);
128 au8522_writereg(state, 0x8121, 0xff);
129 au8522_writereg(state, 0x80a8, 0xf0);
130 au8522_writereg(state, 0x80a9, 0x05);
131 au8522_writereg(state, 0x80aa, 0x77);
132 au8522_writereg(state, 0x80ab, 0xf0);
133 au8522_writereg(state, 0x80ac, 0x05);
134 au8522_writereg(state, 0x80ad, 0x77);
135 au8522_writereg(state, 0x80ae, 0x41);
136 au8522_writereg(state, 0x80af, 0x66);
137 au8522_writereg(state, 0x821b, 0xcc);
138 au8522_writereg(state, 0x821d, 0x80);
139 au8522_writereg(state, 0x80b5, 0xfb);
140 au8522_writereg(state, 0x80b6, 0x8e);
141 au8522_writereg(state, 0x80b7, 0x39);
142 au8522_writereg(state, 0x80a4, 0xe8);
143 au8522_writereg(state, 0x8231, 0x13);
144 break; 473 break;
145 case QAM_64: 474 case QAM_64:
146 case QAM_256: 475 case QAM_256:
147 au8522_writereg(state, 0x80a3, 0x09); 476 dprintk("%s() QAM 64/256\n", __func__);
148 au8522_writereg(state, 0x80a4, 0x00); 477 for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++)
149 au8522_writereg(state, 0x8081, 0xc4); 478 au8522_writereg(state,
150 au8522_writereg(state, 0x80a5, 0x40); 479 QAM_mod_tab[i].reg,
151 au8522_writereg(state, 0x80b5, 0xfb); 480 QAM_mod_tab[i].data);
152 au8522_writereg(state, 0x80b6, 0x8e);
153 au8522_writereg(state, 0x80b7, 0x39);
154 au8522_writereg(state, 0x80aa, 0x77);
155 au8522_writereg(state, 0x80ad, 0x77);
156 au8522_writereg(state, 0x80a6, 0x67);
157 au8522_writereg(state, 0x8262, 0x20);
158 au8522_writereg(state, 0x821c, 0x30);
159 au8522_writereg(state, 0x80b8, 0x3e);
160 au8522_writereg(state, 0x80b9, 0xf0);
161 au8522_writereg(state, 0x80ba, 0x01);
162 au8522_writereg(state, 0x80bb, 0x18);
163 au8522_writereg(state, 0x80bc, 0x50);
164 au8522_writereg(state, 0x80bd, 0x00);
165 au8522_writereg(state, 0x80be, 0xea);
166 au8522_writereg(state, 0x80bf, 0xef);
167 au8522_writereg(state, 0x80c0, 0xfc);
168 au8522_writereg(state, 0x80c1, 0xbd);
169 au8522_writereg(state, 0x80c2, 0x1f);
170 au8522_writereg(state, 0x80c3, 0xfc);
171 au8522_writereg(state, 0x80c4, 0xdd);
172 au8522_writereg(state, 0x80c5, 0xaf);
173 au8522_writereg(state, 0x80c6, 0x00);
174 au8522_writereg(state, 0x80c7, 0x38);
175 au8522_writereg(state, 0x80c8, 0x30);
176 au8522_writereg(state, 0x80c9, 0x05);
177 au8522_writereg(state, 0x80ca, 0x4a);
178 au8522_writereg(state, 0x80cb, 0xd0);
179 au8522_writereg(state, 0x80cc, 0x01);
180 au8522_writereg(state, 0x80cd, 0xd9);
181 au8522_writereg(state, 0x80ce, 0x6f);
182 au8522_writereg(state, 0x80cf, 0xf9);
183 au8522_writereg(state, 0x80d0, 0x70);
184 au8522_writereg(state, 0x80d1, 0xdf);
185 au8522_writereg(state, 0x80d2, 0xf7);
186 au8522_writereg(state, 0x80d3, 0xc2);
187 au8522_writereg(state, 0x80d4, 0xdf);
188 au8522_writereg(state, 0x80d5, 0x02);
189 au8522_writereg(state, 0x80d6, 0x9a);
190 au8522_writereg(state, 0x80d7, 0xd0);
191 au8522_writereg(state, 0x8250, 0x0d);
192 au8522_writereg(state, 0x8251, 0xcd);
193 au8522_writereg(state, 0x8252, 0xe0);
194 au8522_writereg(state, 0x8253, 0x05);
195 au8522_writereg(state, 0x8254, 0xa7);
196 au8522_writereg(state, 0x8255, 0xff);
197 au8522_writereg(state, 0x8256, 0xed);
198 au8522_writereg(state, 0x8257, 0x5b);
199 au8522_writereg(state, 0x8258, 0xae);
200 au8522_writereg(state, 0x8259, 0xe6);
201 au8522_writereg(state, 0x825a, 0x3d);
202 au8522_writereg(state, 0x825b, 0x0f);
203 au8522_writereg(state, 0x825c, 0x0d);
204 au8522_writereg(state, 0x825d, 0xea);
205 au8522_writereg(state, 0x825e, 0xf2);
206 au8522_writereg(state, 0x825f, 0x51);
207 au8522_writereg(state, 0x8260, 0xf5);
208 au8522_writereg(state, 0x8261, 0x06);
209 au8522_writereg(state, 0x821a, 0x00);
210 au8522_writereg(state, 0x8546, 0x40);
211 au8522_writereg(state, 0x8210, 0x26);
212 au8522_writereg(state, 0x8211, 0xf6);
213 au8522_writereg(state, 0x8212, 0x84);
214 au8522_writereg(state, 0x8213, 0x02);
215 au8522_writereg(state, 0x8502, 0x01);
216 au8522_writereg(state, 0x8121, 0x04);
217 au8522_writereg(state, 0x8122, 0x04);
218 au8522_writereg(state, 0x852e, 0x10);
219 au8522_writereg(state, 0x80a4, 0xca);
220 au8522_writereg(state, 0x80a7, 0x40);
221 au8522_writereg(state, 0x8526, 0x01);
222 break; 481 break;
223 default: 482 default:
224 dprintk("%s() Invalid modulation\n", __func__); 483 dprintk("%s() Invalid modulation\n", __func__);
@@ -321,30 +580,24 @@ static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
321 return 0; 580 return 0;
322} 581}
323 582
324static int au8522_read_mse(struct dvb_frontend *fe) 583static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
325{ 584{
326 struct au8522_state *state = fe->demodulator_priv; 585 struct au8522_state *state = fe->demodulator_priv;
327 int mse = 0; 586 int ret = -EINVAL;
328 587
329 if (state->current_modulation == VSB_8)
330 mse = au8522_readreg(state, 0x4311);
331 else
332 mse = au8522_readreg(state, 0x4522);
333
334 dprintk("%s: %d\n", __func__, mse);
335
336 return mse;
337}
338
339static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
340{
341 dprintk("%s()\n", __func__); 588 dprintk("%s()\n", __func__);
342 589
343 /* FIXME: This is mse, not snr 590 if (state->current_modulation == QAM_256)
344 * TODO: mse2snr */ 591 ret = au8522_qam256_mse2snr_lookup(
345 *snr = au8522_read_mse(fe); 592 au8522_readreg(state, 0x4522), snr);
346 593 else if (state->current_modulation == QAM_64)
347 return 0; 594 ret = au8522_qam64_mse2snr_lookup(
595 au8522_readreg(state, 0x4522), snr);
596 else /* VSB_8 */
597 ret = au8522_vsb_mse2snr_lookup(
598 au8522_readreg(state, 0x4311), snr);
599
600 return ret;
348} 601}
349 602
350static int au8522_read_signal_strength(struct dvb_frontend *fe, 603static int au8522_read_signal_strength(struct dvb_frontend *fe,