summaryrefslogtreecommitdiff
path: root/drivers/stream_input/tv_frontend/dtv_demod/dvbc_func.c (plain)
blob: cf2ea8163947e15d0e3da2233f1cd632c9d6a747
1/*
2* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful, but WITHOUT
10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12* more details.
13*
14* You should have received a copy of the GNU General Public License along
15* with this program; if not, write to the Free Software Foundation, Inc.,
16* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17*
18* Description:
19*/
20#include <linux/kernel.h>
21#include <linux/i2c.h>
22#include <linux/delay.h>
23#include <linux/dvb/aml_demod.h>
24#include "demod_func.h"
25#include <linux/kthread.h>
26
27static int debug_amldvbc = 1;
28#define dprintk(a ...) do { if (debug_amldvbc) printk(a); } while (0)
29
30static struct task_struct *cci_task;
31int cciflag;
32struct timer_list mytimer;
33
34static void dvbc_cci_timer(unsigned long data)
35{
36#if 0
37 int count;
38 int maxCCI_p, re, im, j, i, times, maxCCI, sum, sum1, reg_0xf0, tmp1,
39 tmp, tmp2, reg_0xa8, reg_0xac;
40 int reg_0xa8_t, reg_0xac_t;
41
42 count = 100;
43 if ((((apb_read_reg(QAM_BASE + 0x18)) & 0x1) == 1)) {
44 dprintk("[cci]lock ");
45 if (cciflag == 0) {
46 apb_write_reg(QAM_BASE + 0xa8, 0);
47
48 cciflag = 0;
49 }
50 dprintk("\n");
51 mdelay(500);
52 mod_timer(&mytimer, jiffies + 2 * HZ);
53 return;
54 }
55 if (cciflag == 1) {
56 dprintk("[cci]cciflag is 1,wait 20\n");
57 mdelay(20000);
58 }
59 times = 300;
60 tmp = 0x2be2be3;
61 /*0x2ae4772; IF = 6M, fs = 35M, dec2hex(round(8*IF/fs*2^25)) */
62 tmp2 = 0x2000;
63 tmp1 = 8;
64 reg_0xa8 = 0xc0000000; /* bypass CCI */
65 reg_0xac = 0xc0000000; /* bypass CCI */
66
67 maxCCI = 0;
68 maxCCI_p = 0;
69 for (i = 0; i < times; i++) {
70 /*reg_0xa8 = app_apb_read_reg(0xa8); */
71 reg_0xa8_t = reg_0xa8 + tmp + i * tmp2;
72 apb_write_reg(QAM_BASE + 0xa8, reg_0xa8_t);
73 reg_0xac_t = reg_0xac + tmp - i * tmp2;
74 apb_write_reg(QAM_BASE + 0xac, reg_0xac_t);
75 sum = 0;
76 sum1 = 0;
77 for (j = 0; j < tmp1; j++) {
78 /* msleep(20); */
79 /* mdelay(20); */
80 reg_0xf0 = apb_read_reg(QAM_BASE + 0xf0);
81 re = (reg_0xf0 >> 24) & 0xff;
82 im = (reg_0xf0 >> 16) & 0xff;
83 if (re > 127)
84 /*re = re - 256; */
85 re = 256 - re;
86 if (im > 127)
87 /*im = im - 256; */
88 im = 256 - im;
89
90 sum += re + im;
91 re = (reg_0xf0 >> 8) & 0xff;
92 im = (reg_0xf0 >> 0) & 0xff;
93 if (re > 127)
94 /*re = re - 256; */
95 re = 256 - re;
96 if (im > 127)
97 /*im = im - 256; */
98 im = 256 - im;
99
100 sum1 += re + im;
101 }
102 sum = sum / tmp1;
103 sum1 = sum1 / tmp1;
104 if (sum1 > sum) {
105 sum = sum1;
106 reg_0xa8_t = reg_0xac_t;
107 }
108 if (sum > maxCCI) {
109 maxCCI = sum;
110 if (maxCCI > 24)
111 maxCCI_p = reg_0xa8_t & 0x7fffffff;
112 }
113 if ((sum < 24) && (maxCCI_p > 0))
114 break; /* stop CCI detect. */
115 }
116
117 if (maxCCI_p > 0) {
118 apb_write_reg(QAM_BASE + 0xa8, maxCCI_p & 0x7fffffff);
119 /* enable CCI */
120 apb_write_reg(QAM_BASE + 0xac, maxCCI_p & 0x7fffffff);
121 /* enable CCI */
122 /* if(dvbc.mode == 4) // 256QAM */
123 apb_write_reg(QAM_BASE + 0x54, 0xa25705fa);
124 /**/ cciflag = 1;
125 mdelay(1000);
126 } else {
127 dprintk
128 ("[cci] ------------ find NO CCI -------------------\n");
129 cciflag = 0;
130 }
131
132 dprintk("[cci][%s]--------------------------\n", __func__);
133 mod_timer(&mytimer, jiffies + 2 * HZ);
134 return;
135/* }*/
136#endif
137}
138
139int dvbc_timer_init(void)
140{
141 dprintk("%s\n", __func__);
142 setup_timer(&mytimer, dvbc_cci_timer, (unsigned long)"Hello, world!");
143 mytimer.expires = jiffies + 2 * HZ;
144 add_timer(&mytimer);
145 return 0;
146}
147
148void dvbc_timer_exit(void)
149{
150 dprintk("%s\n", __func__);
151 del_timer(&mytimer);
152}
153
154int dvbc_cci_task(void *data)
155{
156 int count;
157 int maxCCI_p, re, im, j, i, times, maxCCI, sum, sum1, reg_0xf0, tmp1,
158 tmp, tmp2, reg_0xa8, reg_0xac;
159 int reg_0xa8_t, reg_0xac_t;
160
161 count = 100;
162 while (1) {
163 msleep(200);
164 if ((((apb_read_reg(QAM_BASE + 0x18)) & 0x1) == 1)) {
165 dprintk("[cci]lock ");
166 if (cciflag == 0) {
167 apb_write_reg(QAM_BASE + 0xa8, 0);
168 apb_write_reg(QAM_BASE + 0xac, 0);
169 dprintk("no cci ");
170 cciflag = 0;
171 }
172 dprintk("\n");
173 msleep(500);
174 continue;
175 }
176
177 if (cciflag == 1) {
178 dprintk("[cci]cciflag is 1,wait 20\n");
179 msleep(20000);
180 }
181 times = 300;
182 tmp = 0x2be2be3;
183 /*0x2ae4772; IF = 6M,fs = 35M, dec2hex(round(8*IF/fs*2^25)) */
184 tmp2 = 0x2000;
185 tmp1 = 8;
186 reg_0xa8 = 0xc0000000; /* bypass CCI */
187 reg_0xac = 0xc0000000; /* bypass CCI */
188
189 maxCCI = 0;
190 maxCCI_p = 0;
191 for (i = 0; i < times; i++) {
192 /*reg_0xa8 = app_apb_read_reg(0xa8); */
193 reg_0xa8_t = reg_0xa8 + tmp + i * tmp2;
194 apb_write_reg(QAM_BASE + 0xa8, reg_0xa8_t);
195 reg_0xac_t = reg_0xac + tmp - i * tmp2;
196 apb_write_reg(QAM_BASE + 0xac, reg_0xac_t);
197 sum = 0;
198 sum1 = 0;
199 for (j = 0; j < tmp1; j++) {
200 /* msleep(1); */
201 reg_0xf0 = apb_read_reg(QAM_BASE + 0xf0);
202 re = (reg_0xf0 >> 24) & 0xff;
203 im = (reg_0xf0 >> 16) & 0xff;
204 if (re > 127)
205 /*re = re - 256; */
206 re = 256 - re;
207 if (im > 127)
208 /*im = im - 256; */
209 im = 256 - im;
210
211 sum += re + im;
212
213 re = (reg_0xf0 >> 8) & 0xff;
214 im = (reg_0xf0 >> 0) & 0xff;
215 if (re > 127)
216 /*re = re - 256; */
217 re = 256 - re;
218 if (im > 127)
219 /*im = im - 256; */
220 im = 256 - im;
221
222 sum1 += re + im;
223 }
224 sum = sum / tmp1;
225 sum1 = sum1 / tmp1;
226 if (sum1 > sum) {
227 sum = sum1;
228 reg_0xa8_t = reg_0xac_t;
229 }
230 if (sum > maxCCI) {
231 maxCCI = sum;
232 if (maxCCI > 24)
233 maxCCI_p = reg_0xa8_t & 0x7fffffff;
234 }
235
236 if ((sum < 24) && (maxCCI_p > 0))
237 break; /* stop CCI detect. */
238 }
239
240 if (maxCCI_p > 0) {
241 apb_write_reg(QAM_BASE + 0xa8, maxCCI_p & 0x7fffffff);
242 /* enable CCI */
243 apb_write_reg(QAM_BASE + 0xac, maxCCI_p & 0x7fffffff);
244 /* enable CCI */
245 /* if(dvbc.mode == 4) // 256QAM */
246 apb_write_reg(QAM_BASE + 0x54, 0xa25705fa);
247 /**/ cciflag = 1;
248 msleep(1000);
249 } else {
250 cciflag = 0;
251 }
252
253 dprintk("[cci][%s]--------------------------\n", __func__);
254 }
255 return 0;
256}
257
258int dvbc_get_cci_task(void)
259{
260 if (cci_task)
261 return 0;
262 else
263 return 1;
264}
265
266void dvbc_create_cci_task(void)
267{
268 int ret;
269
270 /*apb_write_reg(QAM_BASE+0xa8, 0x42b2ebe3); // enable CCI */
271 /* apb_write_reg(QAM_BASE+0xac, 0x42b2ebe3); // enable CCI */
272/* if(dvbc.mode == 4) // 256QAM*/
273 /* apb_write_reg(QAM_BASE+0x54, 0xa25705fa); // */
274 ret = 0;
275 cci_task = kthread_create(dvbc_cci_task, NULL, "cci_task");
276 if (ret != 0) {
277 dprintk("[%s]Create cci kthread error!\n", __func__);
278 cci_task = NULL;
279 return;
280 }
281 wake_up_process(cci_task);
282 dprintk("[%s]Create cci kthread and wake up!\n", __func__);
283}
284
285void dvbc_kill_cci_task(void)
286{
287 if (cci_task) {
288 kthread_stop(cci_task);
289 cci_task = NULL;
290 dprintk("[%s]kill cci kthread !\n", __func__);
291 }
292}
293
294u32 dvbc_set_qam_mode(unsigned char mode)
295{
296 dprintk("auto change mode ,now mode is %d\n", mode);
297 apb_write_reg(QAM_BASE + 0x008, (mode & 7));
298 /* qam mode */
299 switch (mode) {
300 case 0: /* 16 QAM */
301 apb_write_reg(QAM_BASE + 0x054, 0x23460224);
302 /* EQ_FIR_CTL, */
303 apb_write_reg(QAM_BASE + 0x068, 0x00c000c0);
304 /* EQ_CRTH_SNR */
305 apb_write_reg(QAM_BASE + 0x074, 0x50001a0);
306 /* EQ_TH_LMS 40db 13db */
307 apb_write_reg(QAM_BASE + 0x07c, 0x003001e9);
308 /* EQ_NORM and EQ_TH_MMA */
309 /*apb_write_reg(QAM_BASE+0x080, 0x000be1ff);
310 * // EQ_TH_SMMA0
311 */
312 apb_write_reg(QAM_BASE + 0x080, 0x000e01fe);
313 /* EQ_TH_SMMA0 */
314 apb_write_reg(QAM_BASE + 0x084, 0x00000000);
315 /* EQ_TH_SMMA1 */
316 apb_write_reg(QAM_BASE + 0x088, 0x00000000);
317 /* EQ_TH_SMMA2 */
318 apb_write_reg(QAM_BASE + 0x08c, 0x00000000);
319 /* EQ_TH_SMMA3 */
320 /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2b);
321 * // AGC_CTRL ALPS tuner
322 */
323 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292b);
324 * // Pilips Tuner
325 */
326 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292d);
327 * // Pilips Tuner
328 */
329 apb_write_reg(QAM_BASE + 0x094, 0x7f80092d);
330 /* Pilips Tuner */
331 apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f66);
332 /* by raymond 20121213 */
333 break;
334
335 case 1: /* 32 QAM */
336 apb_write_reg(QAM_BASE + 0x054, 0x24560506);
337 /* EQ_FIR_CTL, */
338 apb_write_reg(QAM_BASE + 0x068, 0x00c000c0);
339 /* EQ_CRTH_SNR */
340 /*apb_write_reg(QAM_BASE+0x074, 0x5000260);
341 * // EQ_TH_LMS 40db 19db
342 */
343 apb_write_reg(QAM_BASE + 0x074, 0x50001f0);
344 /* EQ_TH_LMS 40db 17.5db */
345 apb_write_reg(QAM_BASE + 0x07c, 0x00500102);
346 /* EQ_TH_MMA 0x000001cc */
347 apb_write_reg(QAM_BASE + 0x080, 0x00077140);
348 /* EQ_TH_SMMA0 */
349 apb_write_reg(QAM_BASE + 0x084, 0x001fb000);
350 /* EQ_TH_SMMA1 */
351 apb_write_reg(QAM_BASE + 0x088, 0x00000000);
352 /* EQ_TH_SMMA2 */
353 apb_write_reg(QAM_BASE + 0x08c, 0x00000000);
354 /* EQ_TH_SMMA3 */
355 /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2b);
356 * // AGC_CTRL ALPS tuner
357 */
358 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292b);
359 * // Pilips Tuner
360 */
361 apb_write_reg(QAM_BASE + 0x094, 0x7f80092b);
362 /* Pilips Tuner */
363 apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f66);
364 /* by raymond 20121213 */
365 break;
366
367 case 2: /* 64 QAM */
368 /*apb_write_reg(QAM_BASE+0x054, 0x2256033a);
369 * // EQ_FIR_CTL,
370 */
371 apb_write_reg(QAM_BASE + 0x054, 0x2336043a);
372 /* EQ_FIR_CTL, by raymond */
373 apb_write_reg(QAM_BASE + 0x068, 0x00c000c0);
374 /* EQ_CRTH_SNR */
375 /*apb_write_reg(QAM_BASE+0x074, 0x5000260);
376 * // EQ_TH_LMS 40db 19db
377 */
378 apb_write_reg(QAM_BASE + 0x074, 0x5000230);
379 /* EQ_TH_LMS 40db 17.5db */
380 apb_write_reg(QAM_BASE + 0x07c, 0x007001bd);
381 /* EQ_TH_MMA */
382 apb_write_reg(QAM_BASE + 0x080, 0x000580ed);
383 /* EQ_TH_SMMA0 */
384 apb_write_reg(QAM_BASE + 0x084, 0x001771fb);
385 /* EQ_TH_SMMA1 */
386 apb_write_reg(QAM_BASE + 0x088, 0x00000000);
387 /* EQ_TH_SMMA2 */
388 apb_write_reg(QAM_BASE + 0x08c, 0x00000000);
389 /* EQ_TH_SMMA3 */
390 /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c);
391 * // AGC_CTRL ALPS tuner
392 */
393 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c);
394 * // Pilips & maxlinear Tuner
395 */
396 apb_write_reg(QAM_BASE + 0x094, 0x7f802b3d);
397 /* Pilips Tuner & maxlinear Tuner */
398 /*apb_write_reg(QAM_BASE+0x094, 0x7f802b3a);
399 * // Pilips Tuner & maxlinear Tuner
400 */
401 apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f66);
402 /* by raymond 20121213 */
403 break;
404
405 case 3: /* 128 QAM */
406 /*apb_write_reg(QAM_BASE+0x054, 0x2557046a);
407 * // EQ_FIR_CTL,
408 */
409 apb_write_reg(QAM_BASE + 0x054, 0x2437067a);
410 /* EQ_FIR_CTL, by raymond 20121213 */
411 apb_write_reg(QAM_BASE + 0x068, 0x00c000d0);
412 /* EQ_CRTH_SNR */
413 /* apb_write_reg(QAM_BASE+0x074, 0x02440240);
414 * // EQ_TH_LMS 18.5db 18db
415 */
416 /* apb_write_reg(QAM_BASE+0x074, 0x04000400);
417 * // EQ_TH_LMS 22db 22.5db
418 */
419 apb_write_reg(QAM_BASE + 0x074, 0x5000260);
420 /* EQ_TH_LMS 40db 19db */
421 /*apb_write_reg(QAM_BASE+0x07c, 0x00b000f2);
422 * // EQ_TH_MMA0x000000b2
423 */
424 apb_write_reg(QAM_BASE + 0x07c, 0x00b00132);
425 /* EQ_TH_MMA0x000000b2 by raymond 20121213 */
426 apb_write_reg(QAM_BASE + 0x080, 0x0003a09d);
427 /* EQ_TH_SMMA0 */
428 apb_write_reg(QAM_BASE + 0x084, 0x000f8150);
429 /* EQ_TH_SMMA1 */
430 apb_write_reg(QAM_BASE + 0x088, 0x001a51f8);
431 /* EQ_TH_SMMA2 */
432 apb_write_reg(QAM_BASE + 0x08c, 0x00000000);
433 /* EQ_TH_SMMA3 */
434 /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c);
435 * // AGC_CTRL ALPS tuner
436 */
437 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c);
438 * // Pilips Tuner
439 */
440 apb_write_reg(QAM_BASE + 0x094, 0x7f80092c);
441 /* Pilips Tuner */
442 apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f66);
443 /* by raymond 20121213 */
444 break;
445
446 case 4: /* 256 QAM */
447 /*apb_write_reg(QAM_BASE+0x054, 0xa2580588);
448 * // EQ_FIR_CTL,
449 */
450 apb_write_reg(QAM_BASE + 0x054, 0xa25905f9);
451 /* EQ_FIR_CTL, by raymond 20121213 */
452 apb_write_reg(QAM_BASE + 0x068, 0x01e00220);
453 /* EQ_CRTH_SNR */
454 /*apb_write_reg(QAM_BASE+0x074, 0x50002a0);
455 * // EQ_TH_LMS 40db 19db
456 */
457 apb_write_reg(QAM_BASE + 0x074, 0x5000270);
458 /* EQ_TH_LMS 40db 19db by raymond 201211213 */
459 apb_write_reg(QAM_BASE + 0x07c, 0x00f001a5);
460 /* EQ_TH_MMA */
461 apb_write_reg(QAM_BASE + 0x080, 0x0002c077);
462 /* EQ_TH_SMMA0 */
463 apb_write_reg(QAM_BASE + 0x084, 0x000bc0fe);
464 /* EQ_TH_SMMA1 */
465 apb_write_reg(QAM_BASE + 0x088, 0x0013f17e);
466 /* EQ_TH_SMMA2 */
467 apb_write_reg(QAM_BASE + 0x08c, 0x01bc01f9);
468 /* EQ_TH_SMMA3 */
469 /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c);
470 * // AGC_CTRL ALPS tuner
471 */
472 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c);
473 * // Pilips Tuner
474 */
475 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292d);
476 * // Maxlinear Tuner
477 */
478 apb_write_reg(QAM_BASE + 0x094, 0x7f80092d);
479 /* Maxlinear Tuner */
480 apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67);
481 /* by raymond 20121213, when adc=35M,sys=70M,
482 * its better than 0x61f2f66
483 */
484 break;
485 default: /*64qam */
486 /*apb_write_reg(QAM_BASE+0x054, 0x2256033a);
487 * // EQ_FIR_CTL,
488 */
489 apb_write_reg(QAM_BASE + 0x054, 0x2336043a);
490 /* EQ_FIR_CTL, by raymond */
491 apb_write_reg(QAM_BASE + 0x068, 0x00c000c0);
492 /* EQ_CRTH_SNR */
493 /*apb_write_reg(QAM_BASE+0x074, 0x5000260);
494 * // EQ_TH_LMS 40db 19db
495 */
496 apb_write_reg(QAM_BASE + 0x074, 0x5000230);
497 /* EQ_TH_LMS 40db 17.5db */
498 apb_write_reg(QAM_BASE + 0x07c, 0x007001bd);
499 /* EQ_TH_MMA */
500 apb_write_reg(QAM_BASE + 0x080, 0x000580ed);
501 /* EQ_TH_SMMA0 */
502 apb_write_reg(QAM_BASE + 0x084, 0x001771fb);
503 /* EQ_TH_SMMA1 */
504 apb_write_reg(QAM_BASE + 0x088, 0x00000000);
505 /* EQ_TH_SMMA2 */
506 apb_write_reg(QAM_BASE + 0x08c, 0x00000000);
507 /* EQ_TH_SMMA3 */
508 /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c);
509 * // AGC_CTRL ALPS tuner
510 */
511 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c);
512 * // Pilips & maxlinear Tuner
513 */
514 apb_write_reg(QAM_BASE + 0x094, 0x7f802b3d);
515 /* Pilips Tuner & maxlinear Tuner */
516 /*apb_write_reg(QAM_BASE+0x094, 0x7f802b3a);
517 * // Pilips Tuner & maxlinear Tuner
518 */
519 apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f66);
520 /* by raymond 20121213 */
521 break;
522 }
523 return 0;
524}
525
526u32 dvbc_get_status(void)
527{
528/* dprintk("c4 is %x\n",apb_read_reg(QAM_BASE+0xc4));*/
529 return apb_read_reg(QAM_BASE + 0xc4) & 0xf;
530}
531EXPORT_SYMBOL(dvbc_get_status);
532
533static u32 dvbc_get_ch_power(void)
534{
535 u32 tmp;
536 u32 ad_power;
537 u32 agc_gain;
538 u32 ch_power;
539
540 tmp = apb_read_reg(QAM_BASE + 0x09c);
541
542 ad_power = (tmp >> 22) & 0x1ff;
543 agc_gain = (tmp >> 0) & 0x7ff;
544
545 ad_power = ad_power >> 4;
546 /* ch_power = lookuptable(agc_gain) + ad_power; TODO */
547 ch_power = (ad_power & 0xffff) + ((agc_gain & 0xffff) << 16);
548
549 return ch_power;
550}
551
552static u32 dvbc_get_snr(void)
553{
554 u32 tmp, snr;
555
556 tmp = apb_read_reg(QAM_BASE + 0x14) & 0xfff;
557 snr = tmp * 100 / 32; /* * 1e2 */
558
559 return snr;
560}
561
562static u32 dvbc_get_ber(void)
563{
564 u32 rs_ber;
565 u32 rs_packet_len;
566
567 rs_packet_len = apb_read_reg(QAM_BASE + 0x10) & 0xffff;
568 rs_ber = apb_read_reg(QAM_BASE + 0x14) >> 12 & 0xfffff;
569
570 /* rs_ber = rs_ber / 204.0 / 8.0 / rs_packet_len; */
571 if (rs_packet_len == 0)
572 rs_ber = 1000000;
573 else
574 rs_ber = rs_ber * 613 / rs_packet_len; /* 1e-6 */
575
576 return rs_ber;
577}
578
579static u32 dvbc_get_per(void)
580{
581 u32 rs_per;
582 u32 rs_packet_len;
583 u32 acc_rs_per_times;
584
585 rs_packet_len = apb_read_reg(QAM_BASE + 0x10) & 0xffff;
586 rs_per = apb_read_reg(QAM_BASE + 0x18) >> 16 & 0xffff;
587
588 acc_rs_per_times = apb_read_reg(QAM_BASE + 0xcc) & 0xffff;
589 /*rs_per = rs_per / rs_packet_len; */
590
591 if (rs_packet_len == 0)
592 rs_per = 10000;
593 else
594 rs_per = 10000 * rs_per / rs_packet_len; /* 1e-4 */
595
596 /*return rs_per; */
597 return acc_rs_per_times;
598}
599
600static u32 dvbc_get_symb_rate(void)
601{
602 u32 tmp;
603 u32 adc_freq;
604 u32 symb_rate;
605
606 adc_freq = apb_read_reg(QAM_BASE + 0x34) >> 16 & 0xffff;
607 tmp = apb_read_reg(QAM_BASE + 0xb8);
608
609 if ((tmp >> 15) == 0)
610 symb_rate = 0;
611 else
612 symb_rate = 10 * (adc_freq << 12) / (tmp >> 15);
613 /* 1e4 */
614
615 return symb_rate;
616}
617
618static int dvbc_get_freq_off(void)
619{
620 int tmp;
621 int symb_rate;
622 int freq_off;
623
624 symb_rate = dvbc_get_symb_rate();
625 tmp = apb_read_reg(QAM_BASE + 0xe0) & 0x3fffffff;
626 if (tmp >> 29 & 1)
627 tmp -= (1 << 30);
628
629 freq_off = ((tmp >> 16) * 25 * (symb_rate >> 10)) >> 3;
630
631 return freq_off;
632}
633
634static void dvbc_set_test_bus(u8 sel)
635{
636 u32 tmp;
637
638 tmp = apb_read_reg(QAM_BASE + 0x08);
639 tmp &= ~(0x1f << 4);
640 tmp |= ((sel & 0x1f) << 4) | (1 << 3);
641 apb_write_reg(QAM_BASE + 0x08, tmp);
642}
643
644void dvbc_get_test_out(u8 sel, u32 len, u32 *buf)
645{
646 int i, cnt;
647
648 dvbc_set_test_bus(sel);
649
650 for (i = 0, cnt = 0; i < len - 4 && cnt < 1000000; i++) {
651 buf[i] = apb_read_reg(QAM_BASE + 0xb0);
652 if (buf[i] >> 11 & 1) {
653 buf[i++] = apb_read_reg(QAM_BASE + 0xb0);
654 buf[i++] = apb_read_reg(QAM_BASE + 0xb0);
655 buf[i++] = apb_read_reg(QAM_BASE + 0xb0);
656 buf[i++] = apb_read_reg(QAM_BASE + 0xb0);
657 } else {
658 i--;
659 }
660
661 cnt++;
662 }
663}
664
665#if 0
666static void dvbc_sw_reset(int addr, int idx)
667{
668 u32 tmp;
669
670 tmp = apb_read_reg(QAM_BASE + addr);
671
672 tmp &= ~(1 << idx);
673 apb_write_reg(QAM_BASE + addr, tmp);
674
675 udelay(1);
676
677 tmp |= (1 << idx);
678 apb_write_reg(QAM_BASE + addr, tmp);
679}
680
681static void dvbc_reset(void)
682{
683 dvbc_sw_reset(0x04, 0);
684}
685
686static void dvbc_eq_reset(void)
687{
688 dvbc_sw_reset(0x50, 3);
689}
690
691static void dvbc_eq_smma_reset(void)
692{
693 dvbc_sw_reset(0xe8, 0);
694}
695#endif
696static void dvbc_reg_initial(struct aml_demod_sta *demod_sta)
697{
698 u32 clk_freq;
699 u32 adc_freq;
700 u8 tuner;
701 u8 ch_mode;
702 u8 agc_mode;
703 u32 ch_freq;
704 u16 ch_if;
705 u16 ch_bw;
706 u16 symb_rate;
707 u32 phs_cfg;
708 int afifo_ctr;
709 int max_frq_off, tmp;
710
711 clk_freq = demod_sta->clk_freq; /* kHz */
712 adc_freq = demod_sta->adc_freq; /* kHz */
713/* adc_freq = 25414;*/
714 tuner = demod_sta->tuner;
715 ch_mode = demod_sta->ch_mode;
716 agc_mode = demod_sta->agc_mode;
717 ch_freq = demod_sta->ch_freq; /* kHz */
718 ch_if = demod_sta->ch_if; /* kHz */
719 ch_bw = demod_sta->ch_bw; /* kHz */
720 symb_rate = demod_sta->symb_rate; /* k/sec */
721 dprintk("ch_if is %d, %d, %d, %d, %d\n",
722 ch_if, ch_mode, ch_freq, ch_bw, symb_rate);
723/* ch_mode=4;*/
724/* apb_write_reg(DEMOD_CFG_BASE,0x00000007);*/
725 /* disable irq */
726 apb_write_reg(QAM_BASE + 0xd0, 0);
727
728 /* reset */
729 /*dvbc_reset(); */
730 apb_write_reg(QAM_BASE + 0x4, apb_read_reg(QAM_BASE + 0x4) & ~(1 << 4));
731 /* disable fsm_en */
732 apb_write_reg(QAM_BASE + 0x4, apb_read_reg(QAM_BASE + 0x4) & ~(1 << 0));
733 /* Sw disable demod */
734 apb_write_reg(QAM_BASE + 0x4, apb_read_reg(QAM_BASE + 0x4) | (1 << 0));
735 /* Sw enable demod */
736
737 apb_write_reg(QAM_BASE + 0x000, 0x00000000);
738 /* QAM_STATUS */
739 apb_write_reg(QAM_BASE + 0x004, 0x00000f00);
740 /* QAM_GCTL0 */
741 apb_write_reg(QAM_BASE + 0x008, (ch_mode & 7));
742 /* qam mode */
743
744 switch (ch_mode) {
745 case 0: /* 16 QAM */
746 apb_write_reg(QAM_BASE + 0x054, 0x23460224);
747 /* EQ_FIR_CTL, */
748 apb_write_reg(QAM_BASE + 0x068, 0x00c000c0);
749 /* EQ_CRTH_SNR */
750 apb_write_reg(QAM_BASE + 0x074, 0x50001a0);
751 /* EQ_TH_LMS 40db 13db */
752 apb_write_reg(QAM_BASE + 0x07c, 0x003001e9);
753 /* EQ_NORM and EQ_TH_MMA */
754 /*apb_write_reg(QAM_BASE+0x080, 0x000be1ff);
755 * // EQ_TH_SMMA0
756 */
757 apb_write_reg(QAM_BASE + 0x080, 0x000e01fe);
758 /* EQ_TH_SMMA0 */
759 apb_write_reg(QAM_BASE + 0x084, 0x00000000);
760 /* EQ_TH_SMMA1 */
761 apb_write_reg(QAM_BASE + 0x088, 0x00000000);
762 /* EQ_TH_SMMA2 */
763 apb_write_reg(QAM_BASE + 0x08c, 0x00000000);
764 /* EQ_TH_SMMA3 */
765 /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2b);
766 * // AGC_CTRL ALPS tuner
767 */
768 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292b);
769 * // Pilips Tuner
770 */
771 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292d);
772 * // Pilips Tuner
773 */
774 apb_write_reg(QAM_BASE + 0x094, 0x7f80092d);
775 /* Pilips Tuner */
776 apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67);
777 /* by raymond 20121213 */
778 break;
779
780 case 1: /* 32 QAM */
781 apb_write_reg(QAM_BASE + 0x054, 0x24560506);
782 /* EQ_FIR_CTL, */
783 apb_write_reg(QAM_BASE + 0x068, 0x00c000c0);
784 /* EQ_CRTH_SNR */
785 /*apb_write_reg(QAM_BASE+0x074, 0x5000260);
786 * // EQ_TH_LMS 40db 19db
787 */
788 apb_write_reg(QAM_BASE + 0x074, 0x50001f0);
789 /* EQ_TH_LMS 40db 17.5db */
790 apb_write_reg(QAM_BASE + 0x07c, 0x00500102);
791 /* EQ_TH_MMA 0x000001cc */
792 apb_write_reg(QAM_BASE + 0x080, 0x00077140);
793 /* EQ_TH_SMMA0 */
794 apb_write_reg(QAM_BASE + 0x084, 0x001fb000);
795 /* EQ_TH_SMMA1 */
796 apb_write_reg(QAM_BASE + 0x088, 0x00000000);
797 /* EQ_TH_SMMA2 */
798 apb_write_reg(QAM_BASE + 0x08c, 0x00000000);
799 /* EQ_TH_SMMA3 */
800 /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2b);
801 * // AGC_CTRL ALPS tuner
802 */
803 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292b);
804 * // Pilips Tuner
805 */
806 apb_write_reg(QAM_BASE + 0x094, 0x7f80092b);
807 /* Pilips Tuner */
808 apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67);
809 /* by raymond 20121213 */
810 break;
811
812 case 2: /* 64 QAM */
813 /*apb_write_reg(QAM_BASE+0x054, 0x2256033a);
814 * // EQ_FIR_CTL,
815 */
816 apb_write_reg(QAM_BASE + 0x054, 0x2336043a);
817 /* EQ_FIR_CTL, by raymond */
818 apb_write_reg(QAM_BASE + 0x068, 0x00c000c0);
819 /* EQ_CRTH_SNR */
820 /*apb_write_reg(QAM_BASE+0x074, 0x5000260);
821 * // EQ_TH_LMS 40db 19db
822 */
823 apb_write_reg(QAM_BASE + 0x074, 0x5000230);
824 /* EQ_TH_LMS 40db 17.5db */
825 apb_write_reg(QAM_BASE + 0x07c, 0x007001bd);
826 /* EQ_TH_MMA */
827 apb_write_reg(QAM_BASE + 0x080, 0x000580ed);
828 /* EQ_TH_SMMA0 */
829 apb_write_reg(QAM_BASE + 0x084, 0x001771fb);
830 /* EQ_TH_SMMA1 */
831 apb_write_reg(QAM_BASE + 0x088, 0x00000000);
832 /* EQ_TH_SMMA2 */
833 apb_write_reg(QAM_BASE + 0x08c, 0x00000000);
834 /* EQ_TH_SMMA3 */
835 /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c);
836 * // AGC_CTRL ALPS tuner
837 */
838 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c);
839 * // Pilips & maxlinear Tuner
840 */
841 apb_write_reg(QAM_BASE + 0x094, 0x7f802b3d);
842 /* Pilips Tuner & maxlinear Tuner */
843 /*apb_write_reg(QAM_BASE+0x094, 0x7f802b3a);
844 * // Pilips Tuner & maxlinear Tuner
845 */
846 apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67);
847 /* by raymond 20121213 */
848 break;
849
850 case 3: /* 128 QAM */
851 /*apb_write_reg(QAM_BASE+0x054, 0x2557046a);
852 * // EQ_FIR_CTL,
853 */
854 apb_write_reg(QAM_BASE + 0x054, 0x2437067a);
855 /* EQ_FIR_CTL, by raymond 20121213 */
856 apb_write_reg(QAM_BASE + 0x068, 0x00c000d0);
857 /* EQ_CRTH_SNR */
858 /* apb_write_reg(QAM_BASE+0x074, 0x02440240);
859 * // EQ_TH_LMS 18.5db 18db
860 */
861 /* apb_write_reg(QAM_BASE+0x074, 0x04000400);
862 * // EQ_TH_LMS 22db 22.5db
863 */
864 apb_write_reg(QAM_BASE + 0x074, 0x5000260);
865 /* EQ_TH_LMS 40db 19db */
866 /*apb_write_reg(QAM_BASE+0x07c, 0x00b000f2);
867 * // EQ_TH_MMA0x000000b2
868 */
869 apb_write_reg(QAM_BASE + 0x07c, 0x00b00132);
870 /* EQ_TH_MMA0x000000b2 by raymond 20121213 */
871 apb_write_reg(QAM_BASE + 0x080, 0x0003a09d);
872 /* EQ_TH_SMMA0 */
873 apb_write_reg(QAM_BASE + 0x084, 0x000f8150);
874 /* EQ_TH_SMMA1 */
875 apb_write_reg(QAM_BASE + 0x088, 0x001a51f8);
876 /* EQ_TH_SMMA2 */
877 apb_write_reg(QAM_BASE + 0x08c, 0x00000000);
878 /* EQ_TH_SMMA3 */
879 /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c);
880 * // AGC_CTRL ALPS tuner
881 */
882 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c);
883 * // Pilips Tuner
884 */
885 apb_write_reg(QAM_BASE + 0x094, 0x7f80092c);
886 /* Pilips Tuner */
887 apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67);
888 /* by raymond 20121213 */
889 break;
890
891 case 4: /* 256 QAM */
892 /*apb_write_reg(QAM_BASE+0x054, 0xa2580588);
893 * // EQ_FIR_CTL,
894 */
895 apb_write_reg(QAM_BASE + 0x054, 0xa25905f9);
896 /* EQ_FIR_CTL, by raymond 20121213 */
897 apb_write_reg(QAM_BASE + 0x068, 0x01e00220);
898 /* EQ_CRTH_SNR */
899 /*apb_write_reg(QAM_BASE+0x074, 0x50002a0);
900 * // EQ_TH_LMS 40db 19db
901 */
902 apb_write_reg(QAM_BASE + 0x074, 0x5000270);
903 /* EQ_TH_LMS 40db 19db by raymond 201211213 */
904 apb_write_reg(QAM_BASE + 0x07c, 0x00f001a5);
905 /* EQ_TH_MMA */
906 apb_write_reg(QAM_BASE + 0x080, 0x0002c077);
907 /* EQ_TH_SMMA0 */
908 apb_write_reg(QAM_BASE + 0x084, 0x000bc0fe);
909 /* EQ_TH_SMMA1 */
910 apb_write_reg(QAM_BASE + 0x088, 0x0013f17e);
911 /* EQ_TH_SMMA2 */
912 apb_write_reg(QAM_BASE + 0x08c, 0x01bc01f9);
913 /* EQ_TH_SMMA3 */
914 /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c);
915 * // AGC_CTRL ALPS tuner
916 */
917 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c);
918 * // Pilips Tuner
919 */
920 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292d);
921 * // Maxlinear Tuner
922 */
923 apb_write_reg(QAM_BASE + 0x094, 0x7f80092d);
924 /* Maxlinear Tuner */
925 apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67);
926 /* by raymond 20121213, when adc=35M,sys=70M,
927 * its better than 0x61f2f66
928 */
929 break;
930 default: /*64qam */
931 /*apb_write_reg(QAM_BASE+0x054, 0x2256033a);
932 * // EQ_FIR_CTL,
933 */
934 apb_write_reg(QAM_BASE + 0x054, 0x2336043a);
935 /* EQ_FIR_CTL, by raymond */
936 apb_write_reg(QAM_BASE + 0x068, 0x00c000c0);
937 /* EQ_CRTH_SNR */
938 /* EQ_TH_LMS 40db 19db */
939 apb_write_reg(QAM_BASE + 0x074, 0x5000230);
940 /* EQ_TH_LMS 40db 17.5db */
941 apb_write_reg(QAM_BASE + 0x07c, 0x007001bd);
942 /* EQ_TH_MMA */
943 apb_write_reg(QAM_BASE + 0x080, 0x000580ed);
944 /* EQ_TH_SMMA0 */
945 apb_write_reg(QAM_BASE + 0x084, 0x001771fb);
946 /* EQ_TH_SMMA1 */
947 apb_write_reg(QAM_BASE + 0x088, 0x00000000);
948 /* EQ_TH_SMMA2 */
949 apb_write_reg(QAM_BASE + 0x08c, 0x00000000);
950 /* EQ_TH_SMMA3 */
951 /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c);
952 * // AGC_CTRL ALPS tuner
953 */
954 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c);
955 * // Pilips & maxlinear Tuner
956 */
957 apb_write_reg(QAM_BASE + 0x094, 0x7f802b3d);
958 /* Pilips Tuner & maxlinear Tuner */
959 /*apb_write_reg(QAM_BASE+0x094, 0x7f802b3a);
960 * // Pilips Tuner & maxlinear Tuner
961 */
962 apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67);
963 /* by raymond 20121213 */
964 break;
965 }
966
967 /*apb_write_reg(QAM_BASE+0x00c, 0xfffffffe);
968 * // adc_cnt, symb_cnt
969 */
970 apb_write_reg(QAM_BASE + 0x00c, 0xffff8ffe);
971 /* adc_cnt, symb_cnt by raymond 20121213 */
972 if (clk_freq == 0)
973 afifo_ctr = 0;
974 else
975 afifo_ctr = (adc_freq * 256 / clk_freq) + 2;
976 if (afifo_ctr > 255)
977 afifo_ctr = 255;
978 apb_write_reg(QAM_BASE + 0x010, (afifo_ctr << 16) | 8000);
979 /* afifo, rs_cnt_cfg */
980
981 /*apb_write_reg(QAM_BASE+0x020, 0x21353e54);
982 * // PHS_reset & TIM_CTRO_ACCURATE sw_tim_select=0
983 */
984 /*apb_write_reg(QAM_BASE+0x020, 0x21b53e54);
985 * //modified by qiancheng
986 */
987 apb_write_reg(QAM_BASE + 0x020, 0x61b53e54);
988 /*modified by qiancheng by raymond 20121208 0x63b53e54 for cci */
989 /* apb_write_reg(QAM_BASE+0x020, 0x6192bfe2);
990 * //modifed by ligg 20130613 auto symb_rate scan
991 */
992 if (adc_freq == 0)
993 phs_cfg = 0;
994 else
995 phs_cfg = (1 << 31) / adc_freq * ch_if / (1 << 8);
996 /* 8*fo/fs*2^20 fo=36.125, fs = 28.57114, = 21d775 */
997 /* dprintk("phs_cfg = %x\n", phs_cfg); */
998 apb_write_reg(QAM_BASE + 0x024, 0x4c000000 | (phs_cfg & 0x7fffff));
999 /* PHS_OFFSET, IF offset, */
1000
1001 if (adc_freq == 0) {
1002 max_frq_off = 0;
1003 } else {
1004 max_frq_off = (1 << 29) / symb_rate;
1005 /* max_frq_off = (400KHz * 2^29) /
1006 * (AD=28571 * symbol_rate=6875)
1007 */
1008 tmp = 40000000 / adc_freq;
1009 max_frq_off = tmp * max_frq_off;
1010 }
1011 dprintk("max_frq_off is %x,\n", max_frq_off);
1012 apb_write_reg(QAM_BASE + 0x02c, max_frq_off & 0x3fffffff);
1013 /* max frequency offset, by raymond 20121208 */
1014
1015 /*apb_write_reg(QAM_BASE+0x030, 0x011bf400);
1016 * // TIM_CTL0 start speed is 0, when know symbol rate
1017 */
1018 apb_write_reg(QAM_BASE + 0x030, 0x245cf451);
1019 /*MODIFIED BY QIANCHENG */
1020/* apb_write_reg(QAM_BASE+0x030, 0x245bf451);
1021 * //modified by ligg 20130613 --auto symb_rate scan
1022 */
1023 apb_write_reg(QAM_BASE + 0x034,
1024 ((adc_freq & 0xffff) << 16) | (symb_rate & 0xffff));
1025
1026 apb_write_reg(QAM_BASE + 0x038, 0x00400000);
1027 /* TIM_SWEEP_RANGE 16000 */
1028
1029/************* hw state machine config **********/
1030 apb_write_reg(QAM_BASE + 0x040, 0x003c);
1031/* configure symbol rate step step 0*/
1032
1033 /* modified 0x44 0x48 */
1034 apb_write_reg(QAM_BASE + 0x044, (symb_rate & 0xffff) * 256);
1035 /* blind search, configure max symbol_rate for 7218 fb=3.6M */
1036 /*apb_write_reg(QAM_BASE+0x048, 3600*256);
1037 * // configure min symbol_rate fb = 6.95M
1038 */
1039 apb_write_reg(QAM_BASE + 0x048, 3400 * 256);
1040 /* configure min symbol_rate fb = 6.95M */
1041
1042 /*apb_write_reg(QAM_BASE+0x0c0, 0xffffff68); // threshold */
1043 /*apb_write_reg(QAM_BASE+0x0c0, 0xffffff6f); // threshold */
1044 /*apb_write_reg(QAM_BASE+0x0c0, 0xfffffd68); // threshold */
1045 /*apb_write_reg(QAM_BASE+0x0c0, 0xffffff68); // threshold */
1046 /*apb_write_reg(QAM_BASE+0x0c0, 0xffffff68); // threshold */
1047 /*apb_write_reg(QAM_BASE+0x0c0, 0xffff2f67);
1048 * // threshold for skyworth
1049 */
1050 /* apb_write_reg(QAM_BASE+0x0c0, 0x061f2f67); // by raymond 20121208 */
1051 /* apb_write_reg(QAM_BASE+0x0c0, 0x061f2f66);
1052 * // by raymond 20121213, remove it to every constellation
1053 */
1054/************* hw state machine config **********/
1055
1056 apb_write_reg(QAM_BASE + 0x04c, 0x00008800); /* reserved */
1057
1058 /*apb_write_reg(QAM_BASE+0x050, 0x00000002); // EQ_CTL0 */
1059 apb_write_reg(QAM_BASE + 0x050, 0x01472002);
1060 /* EQ_CTL0 by raymond 20121208 */
1061
1062 /*apb_write_reg(QAM_BASE+0x058, 0xff550e1e); // EQ_FIR_INITPOS */
1063 apb_write_reg(QAM_BASE + 0x058, 0xff100e1e);
1064 /* EQ_FIR_INITPOS for skyworth */
1065
1066 apb_write_reg(QAM_BASE + 0x05c, 0x019a0000); /* EQ_FIR_INITVAL0 */
1067 apb_write_reg(QAM_BASE + 0x060, 0x019a0000); /* EQ_FIR_INITVAL1 */
1068
1069 /*apb_write_reg(QAM_BASE+0x064, 0x01101128); // EQ_CRTH_TIMES */
1070 apb_write_reg(QAM_BASE + 0x064, 0x010a1128);
1071 /* EQ_CRTH_TIMES for skyworth */
1072 apb_write_reg(QAM_BASE + 0x06c, 0x00041a05); /* EQ_CRTH_PPM */
1073
1074 apb_write_reg(QAM_BASE + 0x070, 0xffb9aa01); /* EQ_CRLP */
1075
1076 /*apb_write_reg(QAM_BASE+0x090, 0x00020bd5); // agc control */
1077 apb_write_reg(QAM_BASE + 0x090, 0x00000bd5); /* agc control */
1078
1079 /* agc control */
1080 /* apb_write_reg(QAM_BASE+0x094, 0x7f800d2c);// AGC_CTRL ALPS tuner */
1081 /* apb_write_reg(QAM_BASE+0x094, 0x7f80292c); // Pilips Tuner */
1082 if ((agc_mode & 1) == 0)
1083 /* freeze if agc */
1084 apb_write_reg(QAM_BASE + 0x094,
1085 apb_read_reg(QAM_BASE + 0x94) | (0x1 << 10));
1086 if ((agc_mode & 2) == 0) {
1087 /* IF control */
1088 /*freeze rf agc */
1089 apb_write_reg(QAM_BASE + 0x094,
1090 apb_read_reg(QAM_BASE + 0x94) | (0x1 << 13));
1091 }
1092 /*Maxlinear Tuner */
1093 /*apb_write_reg(QAM_BASE+0x094, 0x7f80292d); */
1094 apb_write_reg(QAM_BASE + 0x098, 0x9fcc8190);
1095 /* AGC_IFGAIN_CTRL */
1096 /*apb_write_reg(QAM_BASE+0x0a0, 0x0e028c00);
1097 * // AGC_RFGAIN_CTRL 0x0e020800
1098 */
1099 /*apb_write_reg(QAM_BASE+0x0a0, 0x0e03cc00);
1100 * // AGC_RFGAIN_CTRL 0x0e020800
1101 */
1102 /*apb_write_reg(QAM_BASE+0x0a0, 0x0e028700);
1103 * // AGC_RFGAIN_CTRL 0x0e020800 now
1104 */
1105 /*apb_write_reg(QAM_BASE+0x0a0, 0x0e03cd00);
1106 * // AGC_RFGAIN_CTRL 0x0e020800
1107 */
1108 /*apb_write_reg(QAM_BASE+0x0a0, 0x0603cd11);
1109 * // AGC_RFGAIN_CTRL 0x0e020800 by raymond,
1110 * if Adjcent channel test, maybe it need change.20121208 ad invert
1111 */
1112 apb_write_reg(QAM_BASE + 0x0a0, 0x0603cd10);
1113 /* AGC_RFGAIN_CTRL 0x0e020800 by raymond,
1114 * if Adjcent channel test, maybe it need change.
1115 * 20121208 ad invert,20130221, suit for two path channel.
1116 */
1117
1118 apb_write_reg(QAM_BASE + 0x004, apb_read_reg(QAM_BASE + 0x004) | 0x33);
1119 /* IMQ, QAM Enable */
1120
1121 /* start hardware machine */
1122 /*dvbc_sw_reset(0x004, 4); */
1123 apb_write_reg(QAM_BASE + 0x4, apb_read_reg(QAM_BASE + 0x4) | (1 << 4));
1124 apb_write_reg(QAM_BASE + 0x0e8,
1125 (apb_read_reg(QAM_BASE + 0x0e8) | (1 << 2)));
1126
1127 /* clear irq status */
1128 apb_read_reg(QAM_BASE + 0xd4);
1129
1130 /* enable irq */
1131 apb_write_reg(QAM_BASE + 0xd0, 0x7fff << 3);
1132
1133/*auto track*/
1134 /* dvbc_set_auto_symtrack(); */
1135}
1136
1137u32 dvbc_set_auto_symtrack(void)
1138{
1139 apb_write_reg(QAM_BASE + 0x030, 0x245bf45c); /*open track */
1140 apb_write_reg(QAM_BASE + 0x020, 0x61b2bf5c);
1141 apb_write_reg(QAM_BASE + 0x044, (7000 & 0xffff) * 256);
1142 apb_write_reg(QAM_BASE + 0x038, 0x00220000);
1143 apb_write_reg(QAM_BASE + 0x4, apb_read_reg(QAM_BASE + 0x4) & ~(1 << 0));
1144 /* Sw disable demod */
1145 apb_write_reg(QAM_BASE + 0x4, apb_read_reg(QAM_BASE + 0x4) | (1 << 0));
1146 /* Sw enable demod */
1147 return 0;
1148}
1149
1150int dvbc_set_ch(struct aml_demod_sta *demod_sta,
1151 struct aml_demod_i2c *demod_i2c,
1152 struct aml_demod_dvbc *demod_dvbc)
1153{
1154 int ret = 0;
1155 u16 symb_rate;
1156 u8 mode;
1157 u32 ch_freq;
1158
1159 dprintk("f=%d, s=%d, q=%d\n",
1160 demod_dvbc->ch_freq, demod_dvbc->symb_rate, demod_dvbc->mode);
1161 demod_i2c->tuner = 7;
1162 mode = demod_dvbc->mode;
1163 symb_rate = demod_dvbc->symb_rate;
1164 ch_freq = demod_dvbc->ch_freq;
1165 if (mode > 4) {
1166 dprintk("Error: Invalid QAM mode option %d\n", mode);
1167 mode = 2;
1168 ret = -1;
1169 }
1170
1171 if (symb_rate < 1000 || symb_rate > 7000) {
1172 dprintk("Error: Invalid Symbol Rate option %d\n", symb_rate);
1173 symb_rate = 6875;
1174 ret = -1;
1175 }
1176
1177 if (ch_freq < 1000 || ch_freq > 900000) {
1178 dprintk("Error: Invalid Channel Freq option %d\n", ch_freq);
1179 ch_freq = 474000;
1180 ret = -1;
1181 }
1182 /* if (ret != 0) return ret; */
1183 demod_sta->dvb_mode = 0;
1184 demod_sta->ch_mode = mode;
1185 /* 0:16, 1:32, 2:64, 3:128, 4:256 */
1186 demod_sta->agc_mode = 1;
1187 /* 0:NULL, 1:IF, 2:RF, 3:both */
1188 demod_sta->ch_freq = ch_freq;
1189 demod_sta->tuner = demod_i2c->tuner;
1190
1191 if (demod_i2c->tuner == 1)
1192 demod_sta->ch_if = 36130; /* TODO DCT tuner */
1193 else if (demod_i2c->tuner == 2)
1194 demod_sta->ch_if = 4570; /* TODO Maxlinear tuner */
1195 else if (demod_i2c->tuner == 7)
1196 /* demod_sta->ch_if = 5000; // TODO Si2176 tuner */
1197
1198 demod_sta->ch_bw = 8000; /* TODO */
1199 if (demod_sta->ch_if == 0)
1200 demod_sta->ch_if = 5000;
1201 demod_sta->symb_rate = symb_rate;
1202 dvbc_reg_initial(demod_sta);
1203
1204 return ret;
1205}
1206
1207int dvbc_status(struct aml_demod_sta *demod_sta,
1208 struct aml_demod_i2c *demod_i2c,
1209 struct aml_demod_sts *demod_sts)
1210{
1211 struct aml_fe_dev *dev;
1212
1213/* int ftmp, tmp; */
1214 dev = NULL;
1215 demod_sts->ch_sts = apb_read_reg(QAM_BASE + 0x18);
1216 demod_sts->ch_pow = dvbc_get_ch_power();
1217 demod_sts->ch_snr = dvbc_get_snr();
1218 demod_sts->ch_ber = dvbc_get_ber();
1219 demod_sts->ch_per = dvbc_get_per();
1220 demod_sts->symb_rate = dvbc_get_symb_rate();
1221 demod_sts->freq_off = dvbc_get_freq_off();
1222 /*demod_sts->dat0 = apb_read_reg(QAM_BASE+0x28); */
1223/* demod_sts->dat0 = tuner_get_ch_power(demod_i2c);*/
1224 demod_sts->dat1 = tuner_get_ch_power(dev);
1225#if 0
1226
1227 ftmp = demod_sts->ch_sts;
1228 dprintk("[dvbc debug] ch_sts is %x\n", ftmp);
1229 ftmp = demod_sts->ch_snr;
1230 ftmp /= 100;
1231 dprintk("snr %d dB ", ftmp);
1232 ftmp = demod_sts->ch_ber;
1233 dprintk("ber %.d ", ftmp);
1234 tmp = demod_sts->ch_per;
1235 dprintk("per %d ", tmp);
1236 ftmp = demod_sts->symb_rate;
1237 dprintk("srate %.d ", ftmp);
1238 ftmp = demod_sts->freq_off;
1239 dprintk("freqoff %.d kHz ", ftmp);
1240 tmp = demod_sts->dat1;
1241 dprintk("strength %ddb 0xe0 status is %lu ,b4 status is %lu", tmp,
1242 (apb_read_reg(QAM_BASE + 0xe0) & 0xffff),
1243 (apb_read_reg(QAM_BASE + 0xb4) & 0xffff));
1244 dprintk("dagc_gain is %lu ", apb_read_reg(QAM_BASE + 0xa4) & 0x7f);
1245 tmp = demod_sts->ch_pow;
1246 dprintk("power is %ddb\n", (tmp & 0xffff));
1247
1248#endif
1249
1250 return 0;
1251}
1252
1253void dvbc_enable_irq(int dvbc_irq)
1254{
1255 u32 mask;
1256
1257 /* clear status */
1258 apb_read_reg(QAM_BASE + 0xd4);
1259 /* enable irq */
1260 mask = apb_read_reg(QAM_BASE + 0xd0);
1261 mask |= (1 << dvbc_irq);
1262 apb_write_reg(QAM_BASE + 0xd0, mask);
1263}
1264
1265void dvbc_disable_irq(int dvbc_irq)
1266{
1267 u32 mask;
1268
1269 /* disable irq */
1270 mask = apb_read_reg(QAM_BASE + 0xd0);
1271 mask &= ~(1 << dvbc_irq);
1272 apb_write_reg(QAM_BASE + 0xd0, mask);
1273 /* clear status */
1274 apb_read_reg(QAM_BASE + 0xd4);
1275}
1276
1277char *dvbc_irq_name[] = {
1278 " ADC",
1279 " Symbol",
1280 " RS",
1281 " In_Sync0",
1282 " In_Sync1",
1283 " In_Sync2",
1284 " In_Sync3",
1285 " In_Sync4",
1286 "Out_Sync0",
1287 "Out_Sync1",
1288 "Out_Sync2",
1289 "Out_Sync3",
1290 "Out_Sync4",
1291 "In_SyncCo",
1292 "OutSyncCo",
1293 " In_Dagc",
1294 " Out_Dagc",
1295 " Eq_Mode",
1296 "RS_Uncorr"
1297};
1298
1299void dvbc_isr(struct aml_demod_sta *demod_sta)
1300{
1301 u32 stat, mask;
1302 int dvbc_irq;
1303
1304 stat = apb_read_reg(QAM_BASE + 0xd4);
1305 mask = apb_read_reg(QAM_BASE + 0xd0);
1306 stat &= mask;
1307
1308 for (dvbc_irq = 0; dvbc_irq < 20; dvbc_irq++) {
1309 if (stat >> dvbc_irq & 1) {
1310 if (demod_sta->debug)
1311 dprintk("irq: dvbc %2d %s %8x\n",
1312 dvbc_irq, dvbc_irq_name[dvbc_irq],
1313 stat);
1314 /* dvbc_disable_irq(dvbc_irq); */
1315 }
1316 }
1317}
1318
1319int dvbc_isr_islock(void)
1320{
1321#define IN_SYNC4_MASK (0x80)
1322
1323 u32 stat, mask;
1324
1325 stat = apb_read_reg(QAM_BASE + 0xd4);
1326 apb_write_reg(QAM_BASE + 0xd4, 0);
1327 mask = apb_read_reg(QAM_BASE + 0xd0);
1328 stat &= mask;
1329
1330 return (stat & IN_SYNC4_MASK) == IN_SYNC4_MASK;
1331}
1332