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 | |
27 | static int debug_amldvbc = 1; |
28 | #define dprintk(a ...) do { if (debug_amldvbc) printk(a); } while (0) |
29 | |
30 | static struct task_struct *cci_task; |
31 | int cciflag; |
32 | struct timer_list mytimer; |
33 | |
34 | static 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 | |
139 | int 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 | |
148 | void dvbc_timer_exit(void) |
149 | { |
150 | dprintk("%s\n", __func__); |
151 | del_timer(&mytimer); |
152 | } |
153 | |
154 | int 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 | |
258 | int dvbc_get_cci_task(void) |
259 | { |
260 | if (cci_task) |
261 | return 0; |
262 | else |
263 | return 1; |
264 | } |
265 | |
266 | void 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 | |
285 | void 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 | |
294 | u32 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 | |
526 | u32 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 | } |
531 | EXPORT_SYMBOL(dvbc_get_status); |
532 | |
533 | static 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 | |
552 | static 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 | |
562 | static 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 | |
579 | static 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 | |
600 | static 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 | |
618 | static 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 | |
634 | static 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 | |
644 | void 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 |
666 | static 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 | |
681 | static void dvbc_reset(void) |
682 | { |
683 | dvbc_sw_reset(0x04, 0); |
684 | } |
685 | |
686 | static void dvbc_eq_reset(void) |
687 | { |
688 | dvbc_sw_reset(0x50, 3); |
689 | } |
690 | |
691 | static void dvbc_eq_smma_reset(void) |
692 | { |
693 | dvbc_sw_reset(0xe8, 0); |
694 | } |
695 | #endif |
696 | static 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 | |
1137 | u32 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 | |
1150 | int 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 | |
1207 | int 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 | |
1253 | void 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 | |
1265 | void 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 | |
1277 | char *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 | |
1299 | void 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 | |
1319 | int 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 |