aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/drxk_hard.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends/drxk_hard.c')
-rw-r--r--drivers/media/dvb/frontends/drxk_hard.c5016
1 files changed, 5016 insertions, 0 deletions
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c
new file mode 100644
index 000000000000..e6b1499186a5
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxk_hard.c
@@ -0,0 +1,5016 @@
1/*
2 * drxk_hard: DRX-K DVB-C/T demodulator driver
3 *
4 * Copyright (C) 2010-2011 Digital Devices GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/firmware.h>
30#include <linux/i2c.h>
31#include <linux/version.h>
32#include <asm/div64.h>
33
34#include "dvb_frontend.h"
35#include "drxk.h"
36#include "drxk_hard.h"
37
38static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
39static int PowerDownQAM(struct drxk_state *state);
40static int SetDVBTStandard (struct drxk_state *state,enum OperationMode oMode);
41static int SetQAMStandard(struct drxk_state *state,enum OperationMode oMode);
42static int SetQAM(struct drxk_state *state,u16 IntermediateFreqkHz,
43 s32 tunerFreqOffset);
44static int SetDVBTStandard (struct drxk_state *state,enum OperationMode oMode);
45static int DVBTStart(struct drxk_state *state);
46static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz,
47 s32 tunerFreqOffset);
48static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
49static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
50static int SwitchAntennaToQAM(struct drxk_state *state);
51static int SwitchAntennaToDVBT(struct drxk_state *state);
52
53static bool IsDVBT(struct drxk_state *state)
54{
55 return state->m_OperationMode == OM_DVBT;
56}
57
58static bool IsQAM(struct drxk_state *state)
59{
60 return state->m_OperationMode == OM_QAM_ITU_A ||
61 state->m_OperationMode == OM_QAM_ITU_B ||
62 state->m_OperationMode == OM_QAM_ITU_C;
63}
64
65bool IsA1WithPatchCode(struct drxk_state *state)
66{
67 return state->m_DRXK_A1_PATCH_CODE;
68}
69
70bool IsA1WithRomCode(struct drxk_state *state)
71{
72 return state->m_DRXK_A1_ROM_CODE;
73}
74
75#define NOA1ROM 0
76
77#ifndef CHK_ERROR
78 #define CHK_ERROR(s) if ((status = s) < 0) break
79#endif
80
81#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
82#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
83
84#define DEFAULT_MER_83 165
85#define DEFAULT_MER_93 250
86
87#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
88#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
89#endif
90
91#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
92#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
93#endif
94
95#ifndef DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH
96#define DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH (0x06)
97#endif
98
99#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
100#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
101
102#ifndef DRXK_KI_RAGC_ATV
103#define DRXK_KI_RAGC_ATV 4
104#endif
105#ifndef DRXK_KI_IAGC_ATV
106#define DRXK_KI_IAGC_ATV 6
107#endif
108#ifndef DRXK_KI_DAGC_ATV
109#define DRXK_KI_DAGC_ATV 7
110#endif
111
112#ifndef DRXK_KI_RAGC_QAM
113#define DRXK_KI_RAGC_QAM 3
114#endif
115#ifndef DRXK_KI_IAGC_QAM
116#define DRXK_KI_IAGC_QAM 4
117#endif
118#ifndef DRXK_KI_DAGC_QAM
119#define DRXK_KI_DAGC_QAM 7
120#endif
121#ifndef DRXK_KI_RAGC_DVBT
122#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
123#endif
124#ifndef DRXK_KI_IAGC_DVBT
125#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
126#endif
127#ifndef DRXK_KI_DAGC_DVBT
128#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
129#endif
130
131#ifndef DRXK_AGC_DAC_OFFSET
132#define DRXK_AGC_DAC_OFFSET (0x800)
133#endif
134
135#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
136#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
137#endif
138
139#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
140#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
141#endif
142
143#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
144#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
145#endif
146
147#ifndef DRXK_QAM_SYMBOLRATE_MAX
148#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
149#endif
150
151#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
152#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
153#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
154#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
155#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
156#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
157#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
158#define DRXK_BL_ROM_OFFSET_UCODE 0
159
160#define DRXK_BLC_TIMEOUT 100
161
162#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
163#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
164
165#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
166
167#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
168#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
169#endif
170
171#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
172#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
173#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
174#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
175#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
176
177inline u32 MulDiv32(u32 a, u32 b, u32 c)
178{
179 u64 tmp64;
180
181 tmp64 = (u64)a * (u64)b;
182 do_div(tmp64, c);
183
184 return (u32) tmp64;
185}
186
187inline u32 Frac28a(u32 a, u32 c)
188{
189 int i = 0;
190 u32 Q1 = 0;
191 u32 R0 = 0;
192
193 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
194 Q1 = a / c; /* integer part, only the 4 least significant bits
195 will be visible in the result */
196
197 /* division using radix 16, 7 nibbles in the result */
198 for (i = 0; i < 7; i++) {
199 Q1 = (Q1 << 4) | (R0 / c);
200 R0 = (R0 % c) << 4;
201 }
202 /* rounding */
203 if ((R0 >> 3) >= c)
204 Q1++;
205
206 return Q1;
207}
208
209static u32 Log10Times100(u32 x)
210{
211 static const u8 scale = 15;
212 static const u8 indexWidth = 5;
213 u8 i = 0;
214 u32 y = 0;
215 u32 d = 0;
216 u32 k = 0;
217 u32 r = 0;
218 /*
219 log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
220 0 <= n < ((1<<INDEXWIDTH)+1)
221 */
222
223 static const u32 log2lut[] = {
224 0, /* 0.000000 */
225 290941, /* 290941.300628 */
226 573196, /* 573196.476418 */
227 847269, /* 847269.179851 */
228 1113620, /* 1113620.489452 */
229 1372674, /* 1372673.576986 */
230 1624818, /* 1624817.752104 */
231 1870412, /* 1870411.981536 */
232 2109788, /* 2109787.962654 */
233 2343253, /* 2343252.817465 */
234 2571091, /* 2571091.461923 */
235 2793569, /* 2793568.696416 */
236 3010931, /* 3010931.055901 */
237 3223408, /* 3223408.452106 */
238 3431216, /* 3431215.635215 */
239 3634553, /* 3634553.498355 */
240 3833610, /* 3833610.244726 */
241 4028562, /* 4028562.434393 */
242 4219576, /* 4219575.925308 */
243 4406807, /* 4406806.721144 */
244 4590402, /* 4590401.736809 */
245 4770499, /* 4770499.491025 */
246 4947231, /* 4947230.734179 */
247 5120719, /* 5120719.018555 */
248 5291081, /* 5291081.217197 */
249 5458428, /* 5458427.996830 */
250 5622864, /* 5622864.249668 */
251 5784489, /* 5784489.488298 */
252 5943398, /* 5943398.207380 */
253 6099680, /* 6099680.215452 */
254 6253421, /* 6253420.939751 */
255 6404702, /* 6404701.706649 */
256 6553600, /* 6553600.000000 */
257 };
258
259
260 if (x == 0)
261 return (0);
262
263 /* Scale x (normalize) */
264 /* computing y in log(x/y) = log(x) - log(y) */
265 if ((x & ((0xffffffff) << (scale + 1))) == 0) {
266 for (k = scale; k > 0; k--) {
267 if (x & (((u32)1) << scale))
268 break;
269 x <<= 1;
270 }
271 } else {
272 for (k = scale; k < 31 ; k++) {
273 if ((x & (((u32)(-1)) << (scale+1))) == 0)
274 break;
275 x >>= 1;
276 }
277 }
278 /*
279 Now x has binary point between bit[scale] and bit[scale-1]
280 and 1.0 <= x < 2.0 */
281
282 /* correction for divison: log(x) = log(x/y)+log(y) */
283 y = k * ((((u32)1) << scale) * 200);
284
285 /* remove integer part */
286 x &= ((((u32)1) << scale)-1);
287 /* get index */
288 i = (u8) (x >> (scale - indexWidth));
289 /* compute delta (x - a) */
290 d = x & ((((u32)1) << (scale - indexWidth)) - 1);
291 /* compute log, multiplication (d* (..)) must be within range ! */
292 y += log2lut[i] +
293 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
294 /* Conver to log10() */
295 y /= 108853; /* (log2(10) << scale) */
296 r = (y >> 1);
297 /* rounding */
298 if (y & ((u32)1))
299 r++;
300 return (r);
301}
302
303/****************************************************************************/
304/* I2C **********************************************************************/
305/****************************************************************************/
306
307static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val)
308{
309 struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD,
310 .buf = val, .len = 1 }};
311 return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
312}
313
314static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
315{
316 struct i2c_msg msg =
317 {.addr = adr, .flags = 0, .buf = data, .len = len};
318
319 if (i2c_transfer(adap, &msg, 1) != 1) {
320 printk("i2c_write error\n");
321 return -1;
322 }
323 return 0;
324}
325
326static int i2c_read(struct i2c_adapter *adap,
327 u8 adr, u8 *msg, int len, u8 *answ, int alen)
328{
329 struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0,
330 .buf = msg, .len = len},
331 { .addr = adr, .flags = I2C_M_RD,
332 .buf = answ, .len = alen } };
333 if (i2c_transfer(adap, msgs, 2) != 2) {
334 printk("i2c_read error\n");
335 return -1;
336 }
337 return 0;
338}
339
340static int Read16(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
341{
342 u8 adr=state->demod_address, mm1[4], mm2[2], len;
343#ifdef I2C_LONG_ADR
344 flags |= 0xC0;
345#endif
346 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
347 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
348 mm1[1] = ((reg >> 16) & 0xFF);
349 mm1[2] = ((reg >> 24) & 0xFF) | flags;
350 mm1[3] = ((reg >> 7) & 0xFF);
351 len = 4;
352 } else {
353 mm1[0] = ((reg << 1) & 0xFF);
354 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
355 len = 2;
356 }
357 if (i2c_read(state->i2c, adr, mm1, len, mm2, 2) < 0)
358 return -1;
359 if (data)
360 *data = mm2[0] | (mm2[1] << 8);
361 return 0;
362}
363
364static int Read16_0(struct drxk_state *state, u32 reg, u16 *data)
365{
366 return Read16(state, reg, data, 0);
367}
368
369static int Read32(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
370{
371 u8 adr = state->demod_address, mm1[4], mm2[4], len;
372#ifdef I2C_LONG_ADR
373 flags |= 0xC0;
374#endif
375 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
376 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
377 mm1[1] = ((reg >> 16) & 0xFF);
378 mm1[2] = ((reg >> 24) & 0xFF) | flags;
379 mm1[3] = ((reg >> 7) & 0xFF);
380 len = 4;
381 } else {
382 mm1[0] = ((reg << 1) & 0xFF);
383 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
384 len = 2;
385 }
386 if (i2c_read(state->i2c, adr, mm1, len, mm2, 4) < 0)
387 return -1;
388 if (data)
389 *data = mm2[0] | (mm2[1] << 8) |
390 (mm2[2] << 16) | (mm2[3] << 24);
391 return 0;
392}
393
394static int Write16(struct drxk_state *state, u32 reg, u16 data, u8 flags)
395{
396 u8 adr = state->demod_address, mm[6], len;
397#ifdef I2C_LONG_ADR
398 flags |= 0xC0;
399#endif
400 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
401 mm[0] = (((reg << 1) & 0xFF) | 0x01);
402 mm[1] = ((reg >> 16) & 0xFF);
403 mm[2] = ((reg >> 24) & 0xFF) | flags;
404 mm[3] = ((reg >> 7) & 0xFF);
405 len = 4;
406 } else {
407 mm[0] = ((reg << 1) & 0xFF);
408 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
409 len = 2;
410 }
411 mm[len] = data & 0xff;
412 mm[len+1] = (data >>8) & 0xff;
413 if (i2c_write(state->i2c, adr, mm, len + 2) < 0)
414 return -1;
415 return 0;
416}
417
418static int Write16_0(struct drxk_state *state, u32 reg, u16 data)
419{
420 return Write16(state, reg, data, 0);
421}
422
423static int Write32(struct drxk_state *state, u32 reg, u32 data, u8 flags)
424{
425 u8 adr = state->demod_address, mm[8], len;
426#ifdef I2C_LONG_ADR
427 flags |= 0xC0;
428#endif
429 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
430 mm[0] = (((reg << 1) & 0xFF) | 0x01);
431 mm[1] = ((reg >> 16) & 0xFF);
432 mm[2] = ((reg >> 24) & 0xFF) | flags;
433 mm[3] = ((reg >> 7) & 0xFF);
434 len = 4;
435 } else {
436 mm[0] = ((reg << 1) & 0xFF);
437 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
438 len = 2;
439 }
440 mm[len] = data & 0xff;
441 mm[len+1] = (data >> 8) & 0xff;
442 mm[len+2] = (data >> 16) & 0xff;
443 mm[len+3] = (data >> 24) & 0xff;
444 if (i2c_write(state->i2c, adr, mm, len+4) < 0)
445 return -1;
446 return 0;
447}
448
449static int WriteBlock(struct drxk_state *state, u32 Address,
450 const int BlockSize, const u8 pBlock[], u8 Flags)
451{
452 int status = 0, BlkSize = BlockSize;
453#ifdef I2C_LONG_ADR
454 Flags |= 0xC0;
455#endif
456 while (BlkSize > 0) {
457 int Chunk = BlkSize > state->m_ChunkSize ?
458 state->m_ChunkSize : BlkSize ;
459 u8 *AdrBuf = &state->Chunk[0];
460 u32 AdrLength = 0;
461
462 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
463 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
464 AdrBuf[1] = ((Address >> 16) & 0xFF);
465 AdrBuf[2] = ((Address >> 24) & 0xFF);
466 AdrBuf[3] = ((Address >> 7) & 0xFF);
467 AdrBuf[2] |= Flags;
468 AdrLength = 4;
469 if (Chunk == state->m_ChunkSize)
470 Chunk -= 2;
471 } else {
472 AdrBuf[0] = ((Address << 1) & 0xFF);
473 AdrBuf[1] = (((Address >> 16) & 0x0F) |
474 ((Address >> 18) & 0xF0));
475 AdrLength = 2;
476 }
477 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
478 status = i2c_write(state->i2c, state->demod_address,
479 &state->Chunk[0], Chunk+AdrLength);
480 if (status<0) {
481 printk("I2C Write error\n");
482 break;
483 }
484 pBlock += Chunk;
485 Address += (Chunk >> 1);
486 BlkSize -= Chunk;
487 }
488 return status;
489}
490
491#ifndef DRXK_MAX_RETRIES_POWERUP
492#define DRXK_MAX_RETRIES_POWERUP 20
493#endif
494
495int PowerUpDevice(struct drxk_state *state)
496{
497 int status;
498 u8 data = 0;
499 u16 retryCount = 0;
500
501 status = i2c_read1(state->i2c, state->demod_address, &data);
502 if (status<0)
503 do {
504 data = 0;
505 if (i2c_write(state->i2c,
506 state->demod_address, &data, 1) < 0)
507 printk("powerup failed\n");
508 msleep(10);
509 retryCount++ ;
510 } while (i2c_read1(state->i2c,
511 state->demod_address, &data) < 0 &&
512 (retryCount < DRXK_MAX_RETRIES_POWERUP));
513 if (retryCount >= DRXK_MAX_RETRIES_POWERUP)
514 return -1;
515 do {
516 /* Make sure all clk domains are active */
517 CHK_ERROR(Write16_0(state, SIO_CC_PWD_MODE__A,
518 SIO_CC_PWD_MODE_LEVEL_NONE));
519 CHK_ERROR(Write16_0(state, SIO_CC_UPDATE__A,
520 SIO_CC_UPDATE_KEY));
521 /* Enable pll lock tests */
522 CHK_ERROR(Write16_0(state, SIO_CC_PLL_LOCK__A, 1));
523 state->m_currentPowerMode = DRX_POWER_UP;
524 } while (0);
525 return status;
526}
527
528
529static int init_state(struct drxk_state *state)
530{
531 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
532 u32 ulVSBIfAgcOutputLevel = 0;
533 u32 ulVSBIfAgcMinLevel = 0;
534 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
535 u32 ulVSBIfAgcSpeed = 3;
536
537 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
538 u32 ulVSBRfAgcOutputLevel = 0;
539 u32 ulVSBRfAgcMinLevel = 0;
540 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
541 u32 ulVSBRfAgcSpeed = 3;
542 u32 ulVSBRfAgcTop = 9500;
543 u32 ulVSBRfAgcCutOffCurrent = 4000;
544
545 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
546 u32 ulATVIfAgcOutputLevel = 0;
547 u32 ulATVIfAgcMinLevel = 0;
548 u32 ulATVIfAgcMaxLevel = 0;
549 u32 ulATVIfAgcSpeed = 3;
550
551 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
552 u32 ulATVRfAgcOutputLevel = 0;
553 u32 ulATVRfAgcMinLevel = 0;
554 u32 ulATVRfAgcMaxLevel = 0;
555 u32 ulATVRfAgcTop = 9500;
556 u32 ulATVRfAgcCutOffCurrent = 4000;
557 u32 ulATVRfAgcSpeed = 3;
558
559 u32 ulQual83 = DEFAULT_MER_83;
560 u32 ulQual93 = DEFAULT_MER_93;
561
562 u32 ulDVBTStaticTSClock = 1;
563 u32 ulDVBCStaticTSClock = 1;
564
565 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
566 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
567
568 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
569 /* io_pad_cfg_mode output mode is drive always */
570 /* io_pad_cfg_drive is set to power 2 (23 mA) */
571 u32 ulGPIOCfg = 0x0113;
572 u32 ulGPIO = 0;
573 u32 ulSerialMode = 1;
574 u32 ulInvertTSClock = 0;
575 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
576 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
577 u32 ulDVBTBitrate = 50000000;
578 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
579
580 u32 ulInsertRSByte = 0;
581
582 u32 ulRfMirror = 1;
583 u32 ulPowerDown = 0;
584
585 u32 ulAntennaDVBT = 1;
586 u32 ulAntennaDVBC = 0;
587 u32 ulAntennaSwitchDVBTDVBC = 0;
588
589 state->m_hasLNA = false;
590 state->m_hasDVBT= false;
591 state->m_hasDVBC= false;
592 state->m_hasATV= false;
593 state->m_hasOOB = false;
594 state->m_hasAudio = false;
595
596 state->m_ChunkSize = 124;
597
598 state->m_oscClockFreq = 0;
599 state->m_smartAntInverted = false;
600 state->m_bPDownOpenBridge = false;
601
602 /* real system clock frequency in kHz */
603 state->m_sysClockFreq = 151875;
604 /* Timing div, 250ns/Psys */
605 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
606 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
607 HI_I2C_DELAY) / 1000;
608 /* Clipping */
609 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
610 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
611 state->m_HICfgWakeUpKey = (state->demod_address << 1);
612 /* port/bridge/power down ctrl */
613 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
614
615 state->m_bPowerDown = (ulPowerDown != 0);
616
617 state->m_DRXK_A1_PATCH_CODE = false;
618 state->m_DRXK_A1_ROM_CODE = false;
619 state->m_DRXK_A2_ROM_CODE = false;
620 state->m_DRXK_A3_ROM_CODE = false;
621 state->m_DRXK_A2_PATCH_CODE = false;
622 state->m_DRXK_A3_PATCH_CODE = false;
623
624 /* Init AGC and PGA parameters */
625 /* VSB IF */
626 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
627 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
628 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
629 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
630 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
631 state->m_vsbPgaCfg = 140;
632
633 /* VSB RF */
634 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
635 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
636 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
637 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
638 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
639 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
640 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
641 state->m_vsbPreSawCfg.reference = 0x07;
642 state->m_vsbPreSawCfg.usePreSaw = true;
643
644 state->m_Quality83percent = DEFAULT_MER_83;
645 state->m_Quality93percent = DEFAULT_MER_93;
646 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
647 state->m_Quality83percent = ulQual83;
648 state->m_Quality93percent = ulQual93;
649 }
650
651 /* ATV IF */
652 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
653 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
654 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
655 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
656 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
657
658 /* ATV RF */
659 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
660 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
661 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
662 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
663 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
664 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
665 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
666 state->m_atvPreSawCfg.reference = 0x04;
667 state->m_atvPreSawCfg.usePreSaw = true;
668
669
670 /* DVBT RF */
671 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
672 state->m_dvbtRfAgcCfg.outputLevel = 0;
673 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
674 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
675 state->m_dvbtRfAgcCfg.top = 0x2100;
676 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
677 state->m_dvbtRfAgcCfg.speed = 1;
678
679
680 /* DVBT IF */
681 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
682 state->m_dvbtIfAgcCfg.outputLevel = 0;
683 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
684 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
685 state->m_dvbtIfAgcCfg.top = 13424;
686 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
687 state->m_dvbtIfAgcCfg.speed = 3;
688 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
689 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
690 // state->m_dvbtPgaCfg = 140;
691
692 state->m_dvbtPreSawCfg.reference = 4;
693 state->m_dvbtPreSawCfg.usePreSaw = false;
694
695 /* QAM RF */
696 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
697 state->m_qamRfAgcCfg.outputLevel = 0;
698 state->m_qamRfAgcCfg.minOutputLevel = 6023;
699 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
700 state->m_qamRfAgcCfg.top = 0x2380;
701 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
702 state->m_qamRfAgcCfg.speed = 3;
703
704 /* QAM IF */
705 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
706 state->m_qamIfAgcCfg.outputLevel = 0;
707 state->m_qamIfAgcCfg.minOutputLevel = 0;
708 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
709 state->m_qamIfAgcCfg.top = 0x0511;
710 state->m_qamIfAgcCfg.cutOffCurrent = 0;
711 state->m_qamIfAgcCfg.speed = 3;
712 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
713 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
714
715 state->m_qamPgaCfg = 140;
716 state->m_qamPreSawCfg.reference = 4;
717 state->m_qamPreSawCfg.usePreSaw = false;
718
719 state->m_OperationMode = OM_NONE;
720 state->m_DrxkState = DRXK_UNINITIALIZED;
721
722 /* MPEG output configuration */
723 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
724 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
725 state->m_enableParallel = true; /* If TRUE;
726 parallel out otherwise serial */
727 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
728 state->m_invertERR = false; /* If TRUE; invert ERR signal */
729 state->m_invertSTR = false; /* If TRUE; invert STR signals */
730 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
731 state->m_invertCLK =
732 (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
733 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
734 state->m_DVBCStaticCLK =
735 (ulDVBCStaticTSClock != 0);
736 /* If TRUE; static MPEG clockrate will be used;
737 otherwise clockrate will adapt to the bitrate of the TS */
738
739 state->m_DVBTBitrate = ulDVBTBitrate;
740 state->m_DVBCBitrate = ulDVBCBitrate;
741
742 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
743 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
744
745 /* Maximum bitrate in b/s in case static clockrate is selected */
746 state->m_mpegTsStaticBitrate = 19392658;
747 state->m_disableTEIhandling = false;
748
749 if (ulInsertRSByte)
750 state->m_insertRSByte = true;
751
752 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
753 if (ulMpegLockTimeOut < 10000)
754 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
755 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
756 if (ulDemodLockTimeOut < 10000)
757 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
758
759 // QAM defaults
760 state->m_Constellation = DRX_CONSTELLATION_AUTO;
761 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
762 state->m_fecRsPlen = 204*8; /* fecRsPlen annex A*/
763 state->m_fecRsPrescale = 1;
764
765 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
766 state->m_agcFastClipCtrlDelay = 0;
767
768 state->m_GPIOCfg = (ulGPIOCfg);
769 state->m_GPIO = (ulGPIO == 0 ? 0 : 1);
770
771 state->m_AntennaDVBT = (ulAntennaDVBT == 0 ? 0 : 1);
772 state->m_AntennaDVBC = (ulAntennaDVBC == 0 ? 0 : 1);
773 state->m_AntennaSwitchDVBTDVBC =
774 (ulAntennaSwitchDVBTDVBC == 0 ? 0 : 1);
775
776 state->m_bPowerDown = false;
777 state->m_currentPowerMode = DRX_POWER_DOWN;
778
779 state->m_enableParallel = (ulSerialMode == 0);
780
781 state->m_rfmirror = (ulRfMirror == 0);
782 state->m_IfAgcPol = false;
783 return 0;
784}
785
786static int DRXX_Open(struct drxk_state *state)
787{
788 int status = 0;
789 u32 jtag = 0;
790 u16 bid = 0;
791 u16 key = 0;
792
793 do {
794 /* stop lock indicator process */
795 CHK_ERROR(Write16_0(state, SCU_RAM_GPIO__A,
796 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE));
797 /* Check device id */
798 CHK_ERROR(Read16(state, SIO_TOP_COMM_KEY__A, &key, 0));
799 CHK_ERROR(Write16_0(state, SIO_TOP_COMM_KEY__A,
800 SIO_TOP_COMM_KEY_KEY));
801 CHK_ERROR(Read32(state, SIO_TOP_JTAGID_LO__A, &jtag, 0));
802 CHK_ERROR(Read16(state, SIO_PDR_UIO_IN_HI__A, &bid, 0));
803 CHK_ERROR(Write16_0(state, SIO_TOP_COMM_KEY__A, key));
804 } while(0);
805 return status;
806}
807
808static int GetDeviceCapabilities(struct drxk_state *state)
809{
810 u16 sioPdrOhwCfg = 0;
811 u32 sioTopJtagidLo = 0;
812 int status;
813
814 do {
815 /* driver 0.9.0 */
816 /* stop lock indicator process */
817 CHK_ERROR(Write16_0(state, SCU_RAM_GPIO__A,
818 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE));
819
820 CHK_ERROR(Write16_0(state, SIO_TOP_COMM_KEY__A, 0xFABA));
821 CHK_ERROR(Read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg, 0));
822 CHK_ERROR(Write16_0(state, SIO_TOP_COMM_KEY__A, 0x0000));
823
824 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
825 case 0:
826 /* ignore (bypass ?) */
827 break;
828 case 1:
829 /* 27 MHz */
830 state->m_oscClockFreq = 27000;
831 break;
832 case 2:
833 /* 20.25 MHz */
834 state->m_oscClockFreq = 20250;
835 break;
836 case 3:
837 /* 4 MHz */
838 state->m_oscClockFreq = 20250;
839 break;
840 default:
841 return -1;
842 }
843 /*
844 Determine device capabilities
845 Based on pinning v14
846 */
847 CHK_ERROR(Read32(state, SIO_TOP_JTAGID_LO__A,
848 &sioTopJtagidLo, 0));
849 /* driver 0.9.0 */
850 switch((sioTopJtagidLo >> 29) & 0xF) {
851 case 0:
852 state->m_deviceSpin = DRXK_SPIN_A1;
853 break;
854 case 2:
855 state->m_deviceSpin = DRXK_SPIN_A2;
856 break;
857 case 3:
858 state->m_deviceSpin = DRXK_SPIN_A3;
859 break;
860 default:
861 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
862 status = -1;
863 break;
864 }
865 switch ((sioTopJtagidLo>>12)&0xFF) {
866 case 0x13:
867 /* typeId = DRX3913K_TYPE_ID */
868 state->m_hasLNA = false;
869 state->m_hasOOB = false;
870 state->m_hasATV = false;
871 state->m_hasAudio = false;
872 state->m_hasDVBT = true;
873 state->m_hasDVBC = true;
874 state->m_hasSAWSW = true;
875 state->m_hasGPIO2 = false;
876 state->m_hasGPIO1 = false;
877 state->m_hasIRQN = false;
878 break;
879 case 0x15:
880 /* typeId = DRX3915K_TYPE_ID */
881 state->m_hasLNA = false;
882 state->m_hasOOB = false;
883 state->m_hasATV = true;
884 state->m_hasAudio = false;
885 state->m_hasDVBT = true;
886 state->m_hasDVBC = false;
887 state->m_hasSAWSW = true;
888 state->m_hasGPIO2 = true;
889 state->m_hasGPIO1 = true;
890 state->m_hasIRQN = false;
891 break;
892 case 0x16:
893 /* typeId = DRX3916K_TYPE_ID */
894 state->m_hasLNA = false;
895 state->m_hasOOB = false;
896 state->m_hasATV = true;
897 state->m_hasAudio = false;
898 state->m_hasDVBT = true;
899 state->m_hasDVBC = false;
900 state->m_hasSAWSW = true;
901 state->m_hasGPIO2 = true;
902 state->m_hasGPIO1 = true;
903 state->m_hasIRQN = false;
904 break;
905 case 0x18:
906 /* typeId = DRX3918K_TYPE_ID */
907 state->m_hasLNA = false;
908 state->m_hasOOB = false;
909 state->m_hasATV = true;
910 state->m_hasAudio = true;
911 state->m_hasDVBT = true;
912 state->m_hasDVBC = false;
913 state->m_hasSAWSW = true;
914 state->m_hasGPIO2 = true;
915 state->m_hasGPIO1 = true;
916 state->m_hasIRQN = false;
917 break;
918 case 0x21:
919 /* typeId = DRX3921K_TYPE_ID */
920 state->m_hasLNA = false;
921 state->m_hasOOB = false;
922 state->m_hasATV = true;
923 state->m_hasAudio = true;
924 state->m_hasDVBT = true;
925 state->m_hasDVBC = true;
926 state->m_hasSAWSW = true;
927 state->m_hasGPIO2 = true;
928 state->m_hasGPIO1 = true;
929 state->m_hasIRQN = false;
930 break;
931 case 0x23:
932 /* typeId = DRX3923K_TYPE_ID */
933 state->m_hasLNA = false;
934 state->m_hasOOB = false;
935 state->m_hasATV = true;
936 state->m_hasAudio = true;
937 state->m_hasDVBT = true;
938 state->m_hasDVBC = true;
939 state->m_hasSAWSW = true;
940 state->m_hasGPIO2 = true;
941 state->m_hasGPIO1 = true;
942 state->m_hasIRQN = false;
943 break;
944 case 0x25:
945 /* typeId = DRX3925K_TYPE_ID */
946 state->m_hasLNA = false;
947 state->m_hasOOB = false;
948 state->m_hasATV = true;
949 state->m_hasAudio = true;
950 state->m_hasDVBT = true;
951 state->m_hasDVBC = true;
952 state->m_hasSAWSW = true;
953 state->m_hasGPIO2 = true;
954 state->m_hasGPIO1 = true;
955 state->m_hasIRQN = false;
956 break;
957 case 0x26:
958 /* typeId = DRX3926K_TYPE_ID */
959 state->m_hasLNA = false;
960 state->m_hasOOB = false;
961 state->m_hasATV = true;
962 state->m_hasAudio = false;
963 state->m_hasDVBT = true;
964 state->m_hasDVBC = true;
965 state->m_hasSAWSW = true;
966 state->m_hasGPIO2 = true;
967 state->m_hasGPIO1 = true;
968 state->m_hasIRQN = false;
969 break;
970 default:
971 printk("DeviceID not supported = %02x\n",
972 ((sioTopJtagidLo>>12)&0xFF));
973 status = -1;
974 break;
975 }
976 } while(0);
977 return status;
978}
979
980static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
981{
982 int status;
983 bool powerdown_cmd;
984
985 //printk("%s\n", __FUNCTION__);
986
987 /* Write command */
988 status = Write16_0(state, SIO_HI_RA_RAM_CMD__A, cmd);
989 if (status < 0)
990 return status;
991 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
992 msleep(1);
993
994 powerdown_cmd =
995 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
996 ((state->m_HICfgCtrl) &
997 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
998 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
999 if (powerdown_cmd == false) {
1000 /* Wait until command rdy */
1001 u32 retryCount = 0;
1002 u16 waitCmd;
1003
1004 do {
1005 msleep(1);
1006 retryCount += 1;
1007 status = Read16(state, SIO_HI_RA_RAM_CMD__A,
1008 &waitCmd, 0);
1009 } while ((status < 0) &&
1010 (retryCount < DRXK_MAX_RETRIES) && (waitCmd != 0));
1011
1012 if (status == 0)
1013 status = Read16(state, SIO_HI_RA_RAM_RES__A,
1014 pResult, 0);
1015 }
1016 return status;
1017}
1018
1019static int HI_CfgCommand(struct drxk_state *state)
1020{
1021 int status;
1022
1023 mutex_lock(&state->mutex);
1024 do {
1025 CHK_ERROR(Write16_0(state,SIO_HI_RA_RAM_PAR_6__A,
1026 state->m_HICfgTimeout));
1027 CHK_ERROR(Write16_0(state,SIO_HI_RA_RAM_PAR_5__A,
1028 state->m_HICfgCtrl));
1029 CHK_ERROR(Write16_0(state,SIO_HI_RA_RAM_PAR_4__A,
1030 state->m_HICfgWakeUpKey));
1031 CHK_ERROR(Write16_0(state,SIO_HI_RA_RAM_PAR_3__A,
1032 state->m_HICfgBridgeDelay));
1033 CHK_ERROR(Write16_0(state,SIO_HI_RA_RAM_PAR_2__A,
1034 state->m_HICfgTimingDiv));
1035 CHK_ERROR(Write16_0(state,SIO_HI_RA_RAM_PAR_1__A,
1036 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY));
1037 CHK_ERROR(HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0));
1038
1039 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1040 } while(0);
1041 mutex_unlock(&state->mutex);
1042 return status;
1043}
1044
1045static int InitHI(struct drxk_state *state)
1046{
1047 state->m_HICfgWakeUpKey = (state->demod_address<<1);
1048 state->m_HICfgTimeout = 0x96FF;
1049 /* port/bridge/power down ctrl */
1050 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
1051 return HI_CfgCommand(state);
1052}
1053
1054static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1055{
1056 int status = -1;
1057 u16 sioPdrMclkCfg = 0;
1058 u16 sioPdrMdxCfg = 0;
1059
1060 do {
1061 /* stop lock indicator process */
1062 CHK_ERROR(Write16_0(state, SCU_RAM_GPIO__A,
1063 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE));
1064
1065 /* MPEG TS pad configuration */
1066 CHK_ERROR(Write16_0(state, SIO_TOP_COMM_KEY__A, 0xFABA));
1067
1068 if (mpegEnable == false) {
1069 /* Set MPEG TS pads to inputmode */
1070 CHK_ERROR(Write16_0(state,
1071 SIO_PDR_MSTRT_CFG__A, 0x0000));
1072 CHK_ERROR(Write16_0(state,
1073 SIO_PDR_MERR_CFG__A, 0x0000));
1074 CHK_ERROR(Write16_0(state,
1075 SIO_PDR_MCLK_CFG__A, 0x0000));
1076 CHK_ERROR(Write16_0(state,
1077 SIO_PDR_MVAL_CFG__A, 0x0000));
1078 CHK_ERROR(Write16_0(state, SIO_PDR_MD0_CFG__A, 0x0000));
1079 CHK_ERROR(Write16_0(state, SIO_PDR_MD1_CFG__A, 0x0000));
1080 CHK_ERROR(Write16_0(state, SIO_PDR_MD2_CFG__A, 0x0000));
1081 CHK_ERROR(Write16_0(state, SIO_PDR_MD3_CFG__A, 0x0000));
1082 CHK_ERROR(Write16_0(state, SIO_PDR_MD4_CFG__A, 0x0000));
1083 CHK_ERROR(Write16_0(state, SIO_PDR_MD5_CFG__A, 0x0000));
1084 CHK_ERROR(Write16_0(state, SIO_PDR_MD6_CFG__A, 0x0000));
1085 CHK_ERROR(Write16_0(state, SIO_PDR_MD7_CFG__A, 0x0000));
1086 } else {
1087 /* Enable MPEG output */
1088 sioPdrMdxCfg =
1089 ((state->m_TSDataStrength <<
1090 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1091 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1092 SIO_PDR_MCLK_CFG_DRIVE__B) | 0x0003);
1093
1094 CHK_ERROR(Write16_0(state, SIO_PDR_MSTRT_CFG__A,
1095 sioPdrMdxCfg));
1096 CHK_ERROR(Write16_0(state, SIO_PDR_MERR_CFG__A,
1097 0x0000)); // Disable
1098 CHK_ERROR(Write16_0(state, SIO_PDR_MVAL_CFG__A,
1099 0x0000)); // Disable
1100 if (state->m_enableParallel == true) {
1101 /* paralel -> enable MD1 to MD7 */
1102 CHK_ERROR(Write16_0(state, SIO_PDR_MD1_CFG__A,
1103 sioPdrMdxCfg));
1104 CHK_ERROR(Write16_0(state, SIO_PDR_MD2_CFG__A,
1105 sioPdrMdxCfg));
1106 CHK_ERROR(Write16_0(state, SIO_PDR_MD3_CFG__A,
1107 sioPdrMdxCfg));
1108 CHK_ERROR(Write16_0(state, SIO_PDR_MD4_CFG__A,
1109 sioPdrMdxCfg));
1110 CHK_ERROR(Write16_0(state, SIO_PDR_MD5_CFG__A,
1111 sioPdrMdxCfg));
1112 CHK_ERROR(Write16_0(state, SIO_PDR_MD6_CFG__A,
1113 sioPdrMdxCfg));
1114 CHK_ERROR(Write16_0(state, SIO_PDR_MD7_CFG__A,
1115 sioPdrMdxCfg));
1116 } else {
1117 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1118 SIO_PDR_MD0_CFG_DRIVE__B) |
1119 0x0003);
1120 /* serial -> disable MD1 to MD7 */
1121 CHK_ERROR(Write16_0(state, SIO_PDR_MD1_CFG__A,
1122 0x0000));
1123 CHK_ERROR(Write16_0(state, SIO_PDR_MD2_CFG__A,
1124 0x0000));
1125 CHK_ERROR(Write16_0(state, SIO_PDR_MD3_CFG__A,
1126 0x0000));
1127 CHK_ERROR(Write16_0(state, SIO_PDR_MD4_CFG__A,
1128 0x0000));
1129 CHK_ERROR(Write16_0(state, SIO_PDR_MD5_CFG__A,
1130 0x0000));
1131 CHK_ERROR(Write16_0(state, SIO_PDR_MD6_CFG__A,
1132 0x0000));
1133 CHK_ERROR(Write16_0(state, SIO_PDR_MD7_CFG__A,
1134 0x0000));
1135 }
1136 CHK_ERROR(Write16_0(state, SIO_PDR_MCLK_CFG__A,
1137 sioPdrMclkCfg));
1138 CHK_ERROR(Write16_0(state, SIO_PDR_MD0_CFG__A,
1139 sioPdrMdxCfg));
1140 }
1141 /* Enable MB output over MPEG pads and ctl input */
1142 CHK_ERROR(Write16_0(state, SIO_PDR_MON_CFG__A, 0x0000));
1143 /* Write nomagic word to enable pdr reg write */
1144 CHK_ERROR(Write16_0(state, SIO_TOP_COMM_KEY__A, 0x0000));
1145 } while(0);
1146 return status;
1147}
1148
1149static int MPEGTSDisable(struct drxk_state *state)
1150{
1151 return MPEGTSConfigurePins(state, false);
1152}
1153
1154static int BLChainCmd(struct drxk_state *state,
1155 u16 romOffset, u16 nrOfElements, u32 timeOut)
1156{
1157 u16 blStatus = 0;
1158 int status;
1159 unsigned long end;
1160
1161 mutex_lock(&state->mutex);
1162 do {
1163 CHK_ERROR(Write16_0(state, SIO_BL_MODE__A,
1164 SIO_BL_MODE_CHAIN));
1165 CHK_ERROR(Write16_0(state, SIO_BL_CHAIN_ADDR__A,
1166 romOffset));
1167 CHK_ERROR(Write16_0(state, SIO_BL_CHAIN_LEN__A,
1168 nrOfElements));
1169 CHK_ERROR(Write16_0(state, SIO_BL_ENABLE__A,
1170 SIO_BL_ENABLE_ON));
1171 end=jiffies+msecs_to_jiffies(timeOut);
1172
1173 do {
1174 msleep(1);
1175 CHK_ERROR(Read16(state, SIO_BL_STATUS__A,
1176 &blStatus, 0));
1177 } while ((blStatus == 0x1) &&
1178 ((time_is_after_jiffies(end))));
1179 if (blStatus == 0x1) {
1180 printk("SIO not ready\n");
1181 mutex_unlock(&state->mutex);
1182 return -1;
1183 }
1184 } while(0);
1185 mutex_unlock(&state->mutex);
1186 return status;
1187}
1188
1189
1190static int DownloadMicrocode(struct drxk_state *state,
1191 const u8 pMCImage[],
1192 u32 Length)
1193{
1194 const u8 *pSrc = pMCImage;
1195 u16 Flags;
1196 u16 Drain;
1197 u32 Address;
1198 u16 nBlocks;
1199 u16 BlockSize;
1200 u16 BlockCRC;
1201 u32 offset = 0;
1202 u32 i;
1203 int status;
1204
1205 /* down the drain (we don care about MAGIC_WORD) */
1206 Drain = (pSrc[0] << 8) | pSrc[1];
1207 pSrc += sizeof(u16); offset += sizeof(u16);
1208 nBlocks = (pSrc[0] << 8) | pSrc[1];
1209 pSrc += sizeof(u16); offset += sizeof(u16);
1210
1211 for (i = 0; i < nBlocks; i += 1) {
1212 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
1213 (pSrc[2] << 8) | pSrc[3];
1214 pSrc += sizeof(u32); offset += sizeof(u32);
1215
1216 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
1217 pSrc += sizeof(u16); offset += sizeof(u16);
1218
1219 Flags = (pSrc[0] << 8) | pSrc[1];
1220 pSrc += sizeof(u16); offset += sizeof(u16);
1221
1222 BlockCRC = (pSrc[0] << 8) | pSrc[1];
1223 pSrc += sizeof(u16); offset += sizeof(u16);
1224 status = WriteBlock(state, Address, BlockSize, pSrc, 0);
1225 if (status<0)
1226 break;
1227 pSrc += BlockSize;
1228 offset += BlockSize;
1229 }
1230 return status;
1231}
1232
1233static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1234{
1235 int status;
1236 u16 data = 0;
1237 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
1238 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1239 unsigned long end;
1240
1241 if (enable == false) {
1242 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
1243 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1244 }
1245
1246 status = (Read16_0(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data));
1247
1248 if (data == desiredStatus) {
1249 /* tokenring already has correct status */
1250 return status;
1251 }
1252 /* Disable/enable dvbt tokenring bridge */
1253 status = Write16_0(state,SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
1254
1255 end=jiffies+msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
1256 do
1257 CHK_ERROR(Read16_0(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data));
1258 while ((data != desiredStatus) &&
1259 ((time_is_after_jiffies(end))));
1260 if (data != desiredStatus) {
1261 printk("SIO not ready\n");
1262 return -1;
1263 }
1264 return status;
1265}
1266
1267static int MPEGTSStop(struct drxk_state *state)
1268{
1269 int status = 0;
1270 u16 fecOcSncMode = 0;
1271 u16 fecOcIprMode = 0;
1272
1273 do {
1274 /* Gracefull shutdown (byte boundaries) */
1275 CHK_ERROR(Read16_0(state, FEC_OC_SNC_MODE__A, &fecOcSncMode));
1276 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1277 CHK_ERROR(Write16_0(state, FEC_OC_SNC_MODE__A, fecOcSncMode));
1278
1279 /* Suppress MCLK during absence of data */
1280 CHK_ERROR(Read16_0(state, FEC_OC_IPR_MODE__A, &fecOcIprMode));
1281 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1282 CHK_ERROR(Write16_0(state, FEC_OC_IPR_MODE__A, fecOcIprMode));
1283 } while (0);
1284 return status;
1285}
1286
1287static int scu_command(struct drxk_state *state,
1288 u16 cmd, u8 parameterLen,
1289 u16 * parameter, u8 resultLen, u16 * result)
1290{
1291#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1292#error DRXK register mapping no longer compatible with this routine!
1293#endif
1294 u16 curCmd = 0;
1295 int status;
1296 unsigned long end;
1297
1298 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1299 ((resultLen > 0) && (result == NULL)))
1300 return -1;
1301
1302 mutex_lock(&state->mutex);
1303 do {
1304 /* assume that the command register is ready
1305 since it is checked afterwards */
1306 u8 buffer[34];
1307 int cnt = 0, ii;
1308
1309 for (ii=parameterLen-1; ii >= 0; ii -= 1) {
1310 buffer[cnt++] = (parameter[ii] & 0xFF);
1311 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1312 }
1313 buffer[cnt++] = (cmd & 0xFF);
1314 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1315
1316 WriteBlock(state, SCU_RAM_PARAM_0__A -
1317 (parameterLen-1), cnt, buffer, 0x00);
1318 /* Wait until SCU has processed command */
1319 end=jiffies+msecs_to_jiffies(DRXK_MAX_WAITTIME);
1320 do {
1321 msleep(1);
1322 CHK_ERROR(Read16_0(state, SCU_RAM_COMMAND__A, &curCmd));
1323 } while (! (curCmd == DRX_SCU_READY) &&
1324 (time_is_after_jiffies(end)));
1325 if (curCmd != DRX_SCU_READY) {
1326 printk("SCU not ready\n");
1327 mutex_unlock(&state->mutex);
1328 return -1;
1329 }
1330 /* read results */
1331 if ((resultLen > 0) && (result != NULL)) {
1332 s16 err;
1333 int ii;
1334
1335 for(ii=resultLen-1; ii >= 0; ii -= 1) {
1336 CHK_ERROR(Read16_0(state,
1337 SCU_RAM_PARAM_0__A - ii,
1338 &result[ii]));
1339 }
1340
1341 /* Check if an error was reported by SCU */
1342 err = (s16)result[0];
1343
1344 /* check a few fixed error codes */
1345 if (err == SCU_RESULT_UNKSTD) {
1346 printk("SCU_RESULT_UNKSTD\n");
1347 mutex_unlock(&state->mutex);
1348 return -1;
1349 } else if (err == SCU_RESULT_UNKCMD) {
1350 printk("SCU_RESULT_UNKCMD\n");
1351 mutex_unlock(&state->mutex);
1352 return -1;
1353 }
1354 /* here it is assumed that negative means error,
1355 and positive no error */
1356 else if (err < 0) {
1357 printk("%s ERROR\n", __FUNCTION__);
1358 mutex_unlock(&state->mutex);
1359 return -1;
1360 }
1361 }
1362 } while(0);
1363 mutex_unlock(&state->mutex);
1364 if (status<0)
1365 {
1366 printk("%s: status = %d\n", __FUNCTION__, status);
1367 }
1368
1369 return status;
1370}
1371
1372static int SetIqmAf(struct drxk_state *state, bool active)
1373{
1374 u16 data = 0;
1375 int status;
1376
1377 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "(%d)\n",active));
1378 //printk("%s\n", __FUNCTION__);
1379
1380 do
1381 {
1382 /* Configure IQM */
1383 CHK_ERROR(Read16_0(state, IQM_AF_STDBY__A , &data));;
1384 if (!active) {
1385 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1386 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1387 | IQM_AF_STDBY_STDBY_PD_STANDBY
1388 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1389 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY
1390 );
1391 // break;
1392 //default:
1393 // break;
1394 //}
1395 } else /* active */ {
1396 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1397 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1398 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1399 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1400 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1401 );
1402 // break;
1403 //default:
1404 // break;
1405 //}
1406 }
1407 CHK_ERROR(Write16_0(state, IQM_AF_STDBY__A , data));
1408 }while(0);
1409 return status;
1410}
1411
1412static int CtrlPowerMode(struct drxk_state *state,
1413 pDRXPowerMode_t mode)
1414{
1415 int status = 0;
1416 u16 sioCcPwdMode = 0;
1417
1418 //printk("%s\n", __FUNCTION__);
1419 /* Check arguments */
1420 if (mode == NULL)
1421 return -1;
1422
1423 switch (*mode) {
1424 case DRX_POWER_UP:
1425 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1426 break;
1427 case DRXK_POWER_DOWN_OFDM:
1428 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1429 break;
1430 case DRXK_POWER_DOWN_CORE:
1431 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1432 break;
1433 case DRXK_POWER_DOWN_PLL:
1434 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1435 break;
1436 case DRX_POWER_DOWN:
1437 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1438 break;
1439 default:
1440 /* Unknow sleep mode */
1441 return -1;
1442 break;
1443 }
1444
1445 /* If already in requested power mode, do nothing */
1446 if (state->m_currentPowerMode == *mode)
1447 return 0;
1448
1449 /* For next steps make sure to start from DRX_POWER_UP mode */
1450 if (state->m_currentPowerMode != DRX_POWER_UP)
1451 {
1452 do {
1453 CHK_ERROR(PowerUpDevice(state));
1454 CHK_ERROR(DVBTEnableOFDMTokenRing(state, true));
1455 } while(0);
1456 }
1457
1458 if (*mode == DRX_POWER_UP) {
1459 /* Restore analog & pin configuartion */
1460 } else {
1461 /* Power down to requested mode */
1462 /* Backup some register settings */
1463 /* Set pins with possible pull-ups connected
1464 to them in input mode */
1465 /* Analog power down */
1466 /* ADC power down */
1467 /* Power down device */
1468 /* stop all comm_exec */
1469 /* Stop and power down previous standard */
1470 do {
1471 switch (state->m_OperationMode) {
1472 case OM_DVBT:
1473 CHK_ERROR(MPEGTSStop(state));
1474 CHK_ERROR(PowerDownDVBT(state, false));
1475 break;
1476 case OM_QAM_ITU_A:
1477 case OM_QAM_ITU_C:
1478 CHK_ERROR(MPEGTSStop(state));
1479 CHK_ERROR(PowerDownQAM(state));
1480 break;
1481 default:
1482 break;
1483 }
1484 CHK_ERROR(DVBTEnableOFDMTokenRing(state, false));
1485 CHK_ERROR(Write16_0(state, SIO_CC_PWD_MODE__A,
1486 sioCcPwdMode));
1487 CHK_ERROR(Write16_0(state, SIO_CC_UPDATE__A,
1488 SIO_CC_UPDATE_KEY));
1489
1490 if (*mode != DRXK_POWER_DOWN_OFDM) {
1491 state->m_HICfgCtrl |=
1492 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1493 CHK_ERROR(HI_CfgCommand(state));
1494 }
1495 } while(0);
1496 }
1497 state->m_currentPowerMode = *mode;
1498 return (status);
1499}
1500
1501static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1502{
1503 DRXPowerMode_t powerMode = DRXK_POWER_DOWN_OFDM;
1504 u16 cmdResult = 0;
1505 u16 data = 0;
1506 int status;
1507
1508 do {
1509 CHK_ERROR(Read16_0(state, SCU_COMM_EXEC__A, &data));
1510 if (data == SCU_COMM_EXEC_ACTIVE) {
1511 /* Send OFDM stop command */
1512 CHK_ERROR(scu_command(state,
1513 SCU_RAM_COMMAND_STANDARD_OFDM |
1514 SCU_RAM_COMMAND_CMD_DEMOD_STOP,
1515 0, NULL, 1, &cmdResult));
1516 /* Send OFDM reset command */
1517 CHK_ERROR(scu_command(state,
1518 SCU_RAM_COMMAND_STANDARD_OFDM |
1519 SCU_RAM_COMMAND_CMD_DEMOD_RESET,
1520 0, NULL, 1, &cmdResult));
1521 }
1522
1523 /* Reset datapath for OFDM, processors first */
1524 CHK_ERROR(Write16_0(state, OFDM_SC_COMM_EXEC__A,
1525 OFDM_SC_COMM_EXEC_STOP));
1526 CHK_ERROR(Write16_0(state, OFDM_LC_COMM_EXEC__A,
1527 OFDM_LC_COMM_EXEC_STOP));
1528 CHK_ERROR(Write16_0(state, IQM_COMM_EXEC__A,
1529 IQM_COMM_EXEC_B_STOP));
1530
1531 /* powerdown AFE */
1532 CHK_ERROR(SetIqmAf(state,false));
1533
1534 /* powerdown to OFDM mode */
1535 if (setPowerMode) {
1536 CHK_ERROR(CtrlPowerMode(state,&powerMode));
1537 }
1538 } while(0);
1539 return status;
1540}
1541
1542static int SetOperationMode(struct drxk_state *state, enum OperationMode oMode)
1543{
1544 int status = 0;
1545
1546 /*
1547 Stop and power down previous standard
1548 TODO investigate total power down instead of partial
1549 power down depending on "previous" standard.
1550 */
1551 do {
1552 /* disable HW lock indicator */
1553 CHK_ERROR (Write16_0(state, SCU_RAM_GPIO__A,
1554 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE));
1555
1556 if (state->m_OperationMode != oMode) {
1557 switch (state->m_OperationMode) {
1558 // OM_NONE was added for start up
1559 case OM_NONE:
1560 break;
1561 case OM_DVBT:
1562 CHK_ERROR(MPEGTSStop(state));
1563 CHK_ERROR(PowerDownDVBT(state,true));
1564 state->m_OperationMode = OM_NONE;
1565 break;
1566 case OM_QAM_ITU_B:
1567 status = -1;
1568 break;
1569 case OM_QAM_ITU_A: /* fallthrough */
1570 case OM_QAM_ITU_C:
1571 CHK_ERROR(MPEGTSStop(state));
1572 CHK_ERROR(PowerDownQAM(state));
1573 state->m_OperationMode = OM_NONE;
1574 break;
1575 default:
1576 status = -1;
1577 }
1578 CHK_ERROR(status);
1579
1580 /*
1581 Power up new standard
1582 */
1583 switch (oMode)
1584 {
1585 case OM_DVBT:
1586 state->m_OperationMode = oMode;
1587 CHK_ERROR(SetDVBTStandard(state, oMode));
1588 break;
1589 case OM_QAM_ITU_B:
1590 status = -1;
1591 break;
1592 case OM_QAM_ITU_A: /* fallthrough */
1593 case OM_QAM_ITU_C:
1594 state->m_OperationMode = oMode;
1595 CHK_ERROR(SetQAMStandard(state,oMode));
1596 break;
1597 default:
1598 status = -1;
1599 }
1600 }
1601 CHK_ERROR(status);
1602 } while(0);
1603 return 0;
1604}
1605
1606static int Start(struct drxk_state *state, s32 offsetFreq,
1607 s32 IntermediateFrequency)
1608{
1609 int status;
1610
1611 do {
1612 u16 IFreqkHz;
1613 s32 OffsetkHz = offsetFreq / 1000;
1614
1615 if (state->m_DrxkState != DRXK_STOPPED &&
1616 state->m_DrxkState != DRXK_DTV_STARTED) {
1617 status = -1;
1618 break;
1619 }
1620 state->m_bMirrorFreqSpect =
1621 (state->param.inversion == INVERSION_ON);
1622
1623 if (IntermediateFrequency < 0) {
1624 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1625 IntermediateFrequency = -IntermediateFrequency;
1626 }
1627
1628 switch(state->m_OperationMode) {
1629 case OM_QAM_ITU_A:
1630 case OM_QAM_ITU_C:
1631 IFreqkHz = (IntermediateFrequency / 1000);
1632 CHK_ERROR(SetQAM(state,IFreqkHz, OffsetkHz));
1633 state->m_DrxkState = DRXK_DTV_STARTED;
1634 break;
1635 case OM_DVBT:
1636 IFreqkHz = (IntermediateFrequency / 1000);
1637 CHK_ERROR(MPEGTSStop(state));
1638 CHK_ERROR(SetDVBT(state,IFreqkHz, OffsetkHz));
1639 CHK_ERROR(DVBTStart(state));
1640 state->m_DrxkState = DRXK_DTV_STARTED;
1641 break;
1642 default:
1643 break;
1644 }
1645 } while(0);
1646 return status;
1647}
1648
1649static int ShutDown(struct drxk_state *state)
1650{
1651 MPEGTSStop(state);
1652 return 0;
1653}
1654
1655static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus, u32 Time)
1656{
1657 int status;
1658
1659 if (pLockStatus == NULL)
1660 return -1;
1661
1662 *pLockStatus = NOT_LOCKED;
1663
1664 /* define the SCU command code */
1665 switch (state->m_OperationMode) {
1666 case OM_QAM_ITU_A:
1667 case OM_QAM_ITU_B:
1668 case OM_QAM_ITU_C:
1669 status = GetQAMLockStatus(state, pLockStatus);
1670 break;
1671 case OM_DVBT:
1672 status = GetDVBTLockStatus(state, pLockStatus);
1673 break;
1674 default:
1675 break;
1676 }
1677 return status;
1678}
1679
1680static int MPEGTSStart(struct drxk_state *state)
1681{
1682 int status = 0;
1683
1684 u16 fecOcSncMode = 0;
1685
1686 do {
1687 /* Allow OC to sync again */
1688 CHK_ERROR(Read16_0(state, FEC_OC_SNC_MODE__A, &fecOcSncMode));
1689 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1690 CHK_ERROR(Write16_0(state, FEC_OC_SNC_MODE__A, fecOcSncMode));
1691 CHK_ERROR(Write16_0(state, FEC_OC_SNC_UNLOCK__A, 1));
1692 } while (0);
1693 return status;
1694}
1695
1696static int MPEGTSDtoInit(struct drxk_state *state)
1697{
1698 int status = -1;
1699
1700 do {
1701 /* Rate integration settings */
1702 CHK_ERROR(Write16_0(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000));
1703 CHK_ERROR(Write16_0(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C));
1704 CHK_ERROR(Write16_0(state, FEC_OC_RCN_GAIN__A, 0x000A));
1705 CHK_ERROR(Write16_0(state, FEC_OC_AVR_PARM_A__A, 0x0008));
1706 CHK_ERROR(Write16_0(state, FEC_OC_AVR_PARM_B__A, 0x0006));
1707 CHK_ERROR(Write16_0(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680));
1708 CHK_ERROR(Write16_0(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080));
1709 CHK_ERROR(Write16_0(state, FEC_OC_TMD_COUNT__A, 0x03F4));
1710
1711 /* Additional configuration */
1712 CHK_ERROR(Write16_0(state, FEC_OC_OCR_INVERT__A, 0));
1713 CHK_ERROR(Write16_0(state, FEC_OC_SNC_LWM__A, 2));
1714 CHK_ERROR(Write16_0(state, FEC_OC_SNC_HWM__A, 12));
1715 } while (0);
1716 return status;
1717}
1718
1719static int MPEGTSDtoSetup(struct drxk_state *state, enum OperationMode oMode)
1720{
1721 int status = -1;
1722
1723 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
1724 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
1725 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
1726 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
1727 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
1728 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
1729 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
1730 u16 fecOcTmdMode = 0;
1731 u16 fecOcTmdIntUpdRate = 0;
1732 u32 maxBitRate = 0;
1733 bool staticCLK = false;
1734
1735 do {
1736 /* Check insertion of the Reed-Solomon parity bytes */
1737 CHK_ERROR(Read16_0(state, FEC_OC_MODE__A, &fecOcRegMode));
1738 CHK_ERROR(Read16_0(state, FEC_OC_IPR_MODE__A,
1739 &fecOcRegIprMode));
1740 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
1741 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
1742 if (state->m_insertRSByte == true) {
1743 /* enable parity symbol forward */
1744 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
1745 /* MVAL disable during parity bytes */
1746 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
1747 /* TS burst length to 204 */
1748 fecOcDtoBurstLen = 204 ;
1749 }
1750
1751 /* Check serial or parrallel output */
1752 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
1753 if (state->m_enableParallel == false) {
1754 /* MPEG data output is serial -> set ipr_mode[0] */
1755 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
1756 }
1757
1758 switch (oMode) {
1759 case OM_DVBT:
1760 maxBitRate = state->m_DVBTBitrate;
1761 fecOcTmdMode = 3;
1762 fecOcRcnCtlRate = 0xC00000;
1763 staticCLK = state->m_DVBTStaticCLK;
1764 break;
1765 case OM_QAM_ITU_A: /* fallthrough */
1766 case OM_QAM_ITU_C:
1767 fecOcTmdMode = 0x0004;
1768 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
1769 maxBitRate = state->m_DVBCBitrate;
1770 staticCLK = state->m_DVBCStaticCLK;
1771 break;
1772 default:
1773 status = -1;
1774 } /* switch (standard) */
1775 CHK_ERROR(status);
1776
1777 /* Configure DTO's */
1778 if (staticCLK ) {
1779 u32 bitRate = 0;
1780
1781 /* Rational DTO for MCLK source (static MCLK rate),
1782 Dynamic DTO for optimal grouping
1783 (avoid intra-packet gaps),
1784 DTO offset enable to sync TS burst with MSTRT */
1785 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
1786 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
1787 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
1788 FEC_OC_FCT_MODE_VIRT_ENA__M);
1789
1790 /* Check user defined bitrate */
1791 bitRate = maxBitRate;
1792 if (bitRate > 75900000UL)
1793 { /* max is 75.9 Mb/s */
1794 bitRate = 75900000UL;
1795 }
1796 /* Rational DTO period:
1797 dto_period = (Fsys / bitrate) - 2
1798
1799 Result should be floored,
1800 to make sure >= requested bitrate
1801 */
1802 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
1803 * 1000) / bitRate);
1804 if (fecOcDtoPeriod <= 2)
1805 fecOcDtoPeriod = 0;
1806 else
1807 fecOcDtoPeriod -= 2;
1808 fecOcTmdIntUpdRate = 8;
1809 } else {
1810 /* (commonAttr->staticCLK == false) => dynamic mode */
1811 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
1812 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
1813 fecOcTmdIntUpdRate = 5;
1814 }
1815
1816 /* Write appropriate registers with requested configuration */
1817 CHK_ERROR(Write16_0(state, FEC_OC_DTO_BURST_LEN__A,
1818 fecOcDtoBurstLen));
1819 CHK_ERROR(Write16_0(state, FEC_OC_DTO_PERIOD__A,
1820 fecOcDtoPeriod));
1821 CHK_ERROR(Write16_0(state, FEC_OC_DTO_MODE__A,
1822 fecOcDtoMode));
1823 CHK_ERROR(Write16_0(state, FEC_OC_FCT_MODE__A,
1824 fecOcFctMode));
1825 CHK_ERROR(Write16_0(state, FEC_OC_MODE__A,
1826 fecOcRegMode));
1827 CHK_ERROR(Write16_0(state, FEC_OC_IPR_MODE__A,
1828 fecOcRegIprMode));
1829
1830 /* Rate integration settings */
1831 CHK_ERROR(Write32(state, FEC_OC_RCN_CTL_RATE_LO__A,
1832 fecOcRcnCtlRate ,0));
1833 CHK_ERROR(Write16_0(state, FEC_OC_TMD_INT_UPD_RATE__A,
1834 fecOcTmdIntUpdRate));
1835 CHK_ERROR(Write16_0(state, FEC_OC_TMD_MODE__A,
1836 fecOcTmdMode));
1837 } while (0);
1838 return status;
1839}
1840
1841static int MPEGTSConfigurePolarity(struct drxk_state *state)
1842{
1843 int status;
1844 u16 fecOcRegIprInvert = 0;
1845
1846 /* Data mask for the output data byte */
1847 u16 InvertDataMask =
1848 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
1849 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
1850 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
1851 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
1852
1853 /* Control selective inversion of output bits */
1854 fecOcRegIprInvert &= (~(InvertDataMask));
1855 if (state->m_invertDATA == true)
1856 fecOcRegIprInvert |= InvertDataMask;
1857 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
1858 if (state->m_invertERR == true)
1859 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
1860 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
1861 if (state->m_invertSTR == true)
1862 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
1863 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
1864 if (state->m_invertVAL == true)
1865 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
1866 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
1867 if (state->m_invertCLK == true)
1868 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
1869 status = Write16_0(state,FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
1870 return status;
1871}
1872
1873#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
1874
1875static int SetAgcRf(struct drxk_state *state,
1876 struct SCfgAgc *pAgcCfg, bool isDTV)
1877{
1878 int status = 0;
1879 struct SCfgAgc *pIfAgcSettings;
1880
1881 if (pAgcCfg == NULL)
1882 return -1;
1883
1884 do {
1885 u16 data = 0;
1886
1887 switch (pAgcCfg->ctrlMode) {
1888 case DRXK_AGC_CTRL_AUTO:
1889
1890 /* Enable RF AGC DAC */
1891 CHK_ERROR(Read16_0(state, IQM_AF_STDBY__A , &data));
1892 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
1893 CHK_ERROR(Write16_0(state, IQM_AF_STDBY__A, data));
1894
1895 CHK_ERROR(Read16(state, SCU_RAM_AGC_CONFIG__A,
1896 &data, 0));
1897
1898 /* Enable SCU RF AGC loop */
1899 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
1900
1901 /* Polarity */
1902 if (state->m_RfAgcPol)
1903 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
1904 else
1905 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
1906 CHK_ERROR(Write16_0(state,
1907 SCU_RAM_AGC_CONFIG__A, data));
1908
1909 /* Set speed (using complementary reduction value) */
1910 CHK_ERROR(Read16(state, SCU_RAM_AGC_KI_RED__A,
1911 &data, 0));
1912
1913 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
1914 data |= (~(pAgcCfg->speed <<
1915 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
1916 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
1917
1918 CHK_ERROR(Write16_0(state,
1919 SCU_RAM_AGC_KI_RED__A, data));
1920
1921 if (IsDVBT(state))
1922 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
1923 else if (IsQAM(state))
1924 pIfAgcSettings = &state->m_qamIfAgcCfg;
1925 else
1926 pIfAgcSettings = &state->m_atvIfAgcCfg;
1927 if (pIfAgcSettings == NULL)
1928 return -1;
1929
1930 /* Set TOP, only if IF-AGC is in AUTO mode */
1931 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
1932 CHK_ERROR(Write16_0(state,
1933 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
1934 pAgcCfg->top));
1935
1936 /* Cut-Off current */
1937 CHK_ERROR(Write16_0(state,
1938 SCU_RAM_AGC_RF_IACCU_HI_CO__A,
1939 pAgcCfg->cutOffCurrent));
1940
1941 /* Max. output level */
1942 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_RF_MAX__A,
1943 pAgcCfg->maxOutputLevel));
1944
1945 break;
1946
1947 case DRXK_AGC_CTRL_USER:
1948 /* Enable RF AGC DAC */
1949 CHK_ERROR(Read16_0(state, IQM_AF_STDBY__A, &data));
1950 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
1951 CHK_ERROR(Write16_0(state, IQM_AF_STDBY__A, data));
1952
1953 /* Disable SCU RF AGC loop */
1954 CHK_ERROR(Read16_0(state,
1955 SCU_RAM_AGC_CONFIG__A, &data));
1956 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
1957 if (state->m_RfAgcPol)
1958 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
1959 else
1960 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
1961 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_CONFIG__A,
1962 data));
1963
1964 /* SCU c.o.c. to 0, enabling full control range */
1965 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
1966 0));
1967
1968 /* Write value to output pin */
1969 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI__A,
1970 pAgcCfg->outputLevel));
1971 break;
1972
1973 case DRXK_AGC_CTRL_OFF:
1974 /* Disable RF AGC DAC */
1975 CHK_ERROR(Read16_0(state, IQM_AF_STDBY__A , &data));
1976 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
1977 CHK_ERROR(Write16_0(state, IQM_AF_STDBY__A , data));
1978
1979 /* Disable SCU RF AGC loop */
1980 CHK_ERROR(Read16_0(state,
1981 SCU_RAM_AGC_CONFIG__A, &data));
1982 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
1983 CHK_ERROR(Write16_0(state,
1984 SCU_RAM_AGC_CONFIG__A, data));
1985 break;
1986
1987 default:
1988 return -1;
1989
1990 } /* switch (agcsettings->ctrlMode) */
1991 } while(0);
1992 return status;
1993}
1994
1995#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
1996
1997static int SetAgcIf (struct drxk_state *state,
1998 struct SCfgAgc *pAgcCfg, bool isDTV)
1999{
2000 u16 data = 0;
2001 int status = 0;
2002 struct SCfgAgc *pRfAgcSettings;
2003
2004 do {
2005 switch (pAgcCfg->ctrlMode) {
2006 case DRXK_AGC_CTRL_AUTO:
2007
2008 /* Enable IF AGC DAC */
2009 CHK_ERROR(Read16_0(state, IQM_AF_STDBY__A , &data));
2010 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2011 CHK_ERROR(Write16_0(state, IQM_AF_STDBY__A , data));
2012
2013 CHK_ERROR(Read16_0(state, SCU_RAM_AGC_CONFIG__A,
2014 &data));
2015
2016 /* Enable SCU IF AGC loop */
2017 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2018
2019 /* Polarity */
2020 if (state->m_IfAgcPol)
2021 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2022 else
2023 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2024 CHK_ERROR(Write16_0(state,
2025 SCU_RAM_AGC_CONFIG__A, data));
2026
2027 /* Set speed (using complementary reduction value) */
2028 CHK_ERROR(Read16_0(state, SCU_RAM_AGC_KI_RED__A,
2029 &data));
2030 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2031 data |= (~(pAgcCfg->speed <<
2032 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2033 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2034
2035 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_KI_RED__A ,
2036 data));
2037
2038 if (IsQAM(state))
2039 pRfAgcSettings = &state->m_qamRfAgcCfg;
2040 else
2041 pRfAgcSettings = &state->m_atvRfAgcCfg;
2042 if (pRfAgcSettings == NULL)
2043 return -1;
2044 /* Restore TOP */
2045 CHK_ERROR(Write16_0(state,
2046 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2047 pRfAgcSettings->top));
2048 break;
2049
2050 case DRXK_AGC_CTRL_USER:
2051
2052 /* Enable IF AGC DAC */
2053 CHK_ERROR(Read16_0(state, IQM_AF_STDBY__A , &data));
2054 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2055 CHK_ERROR(Write16_0(state, IQM_AF_STDBY__A , data));
2056
2057 CHK_ERROR(Read16_0(state,
2058 SCU_RAM_AGC_CONFIG__A, &data));
2059
2060 /* Disable SCU IF AGC loop */
2061 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2062
2063 /* Polarity */
2064 if (state->m_IfAgcPol)
2065 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2066 else
2067 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2068 CHK_ERROR(Write16_0(state,
2069 SCU_RAM_AGC_CONFIG__A, data));
2070
2071 /* Write value to output pin */
2072 CHK_ERROR(Write16_0(state,
2073 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2074 pAgcCfg->outputLevel));
2075 break;
2076
2077 case DRXK_AGC_CTRL_OFF:
2078
2079 /* Disable If AGC DAC */
2080 CHK_ERROR(Read16_0(state, IQM_AF_STDBY__A , &data));
2081 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2082 CHK_ERROR(Write16_0(state, IQM_AF_STDBY__A , data));
2083
2084 /* Disable SCU IF AGC loop */
2085 CHK_ERROR(Read16_0(state,
2086 SCU_RAM_AGC_CONFIG__A, &data));
2087 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2088 CHK_ERROR(Write16_0(state,
2089 SCU_RAM_AGC_CONFIG__A, data));
2090 break;
2091 } /* switch (agcSettingsIf->ctrlMode) */
2092
2093 /* always set the top to support
2094 configurations without if-loop */
2095 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
2096 pAgcCfg->top));
2097
2098
2099 } while(0);
2100 return status;
2101}
2102
2103static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2104{
2105 u16 agcDacLvl;
2106 int status = Read16_0(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2107
2108 *pValue = 0;
2109
2110 if (status==0) {
2111 u16 Level = 0;
2112 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2113 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2114 if (Level < 14000)
2115 *pValue = (14000 - Level) / 4 ;
2116 else
2117 *pValue = 0;
2118 }
2119 return status;
2120}
2121
2122static int GetQAMSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2123{
2124 int status = 0;
2125
2126 do {
2127 /* MER calculation */
2128 u16 qamSlErrPower = 0; /* accum. error between
2129 raw and sliced symbols */
2130 u32 qamSlSigPower = 0; /* used for MER, depends of
2131 QAM constellation */
2132 u32 qamSlMer = 0; /* QAM MER */
2133
2134 /* get the register value needed for MER */
2135 CHK_ERROR(Read16_0(state,QAM_SL_ERR_POWER__A, &qamSlErrPower));
2136
2137 switch(state->param.u.qam.modulation) {
2138 case QAM_16:
2139 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2140 break;
2141 case QAM_32:
2142 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2143 break;
2144 case QAM_64:
2145 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2146 break;
2147 case QAM_128:
2148 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2149 break;
2150 default:
2151 case QAM_256:
2152 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2153 break;
2154 }
2155
2156 if (qamSlErrPower > 0) {
2157 qamSlMer = Log10Times100(qamSlSigPower) -
2158 Log10Times100((u32) qamSlErrPower);
2159 }
2160 *pSignalToNoise = qamSlMer;
2161 } while(0);
2162 return status;
2163}
2164
2165static int GetDVBTSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2166{
2167 int status = 0;
2168
2169 u16 regData = 0;
2170 u32 EqRegTdSqrErrI = 0;
2171 u32 EqRegTdSqrErrQ = 0;
2172 u16 EqRegTdSqrErrExp = 0;
2173 u16 EqRegTdTpsPwrOfs = 0;
2174 u16 EqRegTdReqSmbCnt = 0;
2175 u32 tpsCnt = 0;
2176 u32 SqrErrIQ = 0;
2177 u32 a = 0;
2178 u32 b = 0;
2179 u32 c = 0;
2180 u32 iMER = 0;
2181 u16 transmissionParams = 0;
2182
2183 do {
2184 CHK_ERROR(Read16_0(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A,
2185 &EqRegTdTpsPwrOfs));
2186 CHK_ERROR(Read16_0(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A,
2187 &EqRegTdReqSmbCnt));
2188 CHK_ERROR(Read16_0(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A,
2189 &EqRegTdSqrErrExp));
2190 CHK_ERROR(Read16_0(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A,
2191 &regData));
2192 /* Extend SQR_ERR_I operational range */
2193 EqRegTdSqrErrI = (u32) regData;
2194 if ((EqRegTdSqrErrExp > 11) &&
2195 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2196 EqRegTdSqrErrI += 0x00010000UL;
2197 }
2198 CHK_ERROR(Read16_0(state,OFDM_EQ_TOP_TD_SQR_ERR_Q__A,
2199 &regData));
2200 /* Extend SQR_ERR_Q operational range */
2201 EqRegTdSqrErrQ = (u32)regData;
2202 if ((EqRegTdSqrErrExp > 11) &&
2203 (EqRegTdSqrErrQ < 0x00000FFFUL))
2204 EqRegTdSqrErrQ += 0x00010000UL;
2205
2206 CHK_ERROR(Read16_0(state,OFDM_SC_RA_RAM_OP_PARAM__A,
2207 &transmissionParams));
2208
2209 /* Check input data for MER */
2210
2211 /* MER calculation (in 0.1 dB) without math.h */
2212 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2213 iMER = 0;
2214 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2215 /* No error at all, this must be the HW reset value
2216 * Apparently no first measurement yet
2217 * Set MER to 0.0 */
2218 iMER = 0;
2219 } else {
2220 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2221 EqRegTdSqrErrExp;
2222 if ((transmissionParams &
2223 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2224 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2225 tpsCnt = 17;
2226 else
2227 tpsCnt = 68;
2228
2229 /* IMER = 100 * log10 (x)
2230 where x = (EqRegTdTpsPwrOfs^2 *
2231 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2232
2233 => IMER = a + b -c
2234 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2235 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2236 c = 100 * log10 (SqrErrIQ)
2237 */
2238
2239 /* log(x) x = 9bits * 9bits->18 bits */
2240 a = Log10Times100(EqRegTdTpsPwrOfs*EqRegTdTpsPwrOfs);
2241 /* log(x) x = 16bits * 7bits->23 bits */
2242 b = Log10Times100(EqRegTdReqSmbCnt*tpsCnt);
2243 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2244 c = Log10Times100(SqrErrIQ);
2245
2246 iMER = a + b;
2247 /* No negative MER, clip to zero */
2248 if (iMER > c)
2249 iMER -= c;
2250 else
2251 iMER = 0;
2252 }
2253 *pSignalToNoise = iMER;
2254 } while(0);
2255
2256 return status;
2257}
2258
2259static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2260{
2261 *pSignalToNoise = 0;
2262 switch(state->m_OperationMode) {
2263 case OM_DVBT:
2264 return GetDVBTSignalToNoise(state, pSignalToNoise);
2265 case OM_QAM_ITU_A:
2266 case OM_QAM_ITU_C:
2267 return GetQAMSignalToNoise(state, pSignalToNoise);
2268 default:
2269 break;
2270 }
2271 return 0;
2272}
2273
2274#if 0
2275static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2276{
2277 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2278 int status = 0;
2279
2280 static s32 QE_SN[] =
2281 {
2282 51, // QPSK 1/2
2283 69, // QPSK 2/3
2284 79, // QPSK 3/4
2285 89, // QPSK 5/6
2286 97, // QPSK 7/8
2287 108, // 16-QAM 1/2
2288 131, // 16-QAM 2/3
2289 146, // 16-QAM 3/4
2290 156, // 16-QAM 5/6
2291 160, // 16-QAM 7/8
2292 165, // 64-QAM 1/2
2293 187, // 64-QAM 2/3
2294 202, // 64-QAM 3/4
2295 216, // 64-QAM 5/6
2296 225, // 64-QAM 7/8
2297 };
2298
2299 *pQuality = 0;
2300
2301 do {
2302 s32 SignalToNoise = 0;
2303 u16 Constellation = 0;
2304 u16 CodeRate = 0;
2305 u32 SignalToNoiseRel;
2306 u32 BERQuality;
2307
2308 CHK_ERROR(GetDVBTSignalToNoise(state,&SignalToNoise));
2309 CHK_ERROR(Read16_0(state,OFDM_EQ_TOP_TD_TPS_CONST__A,
2310 &Constellation));
2311 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2312
2313 CHK_ERROR(Read16_0(state,OFDM_EQ_TOP_TD_TPS_CODE_HP__A,
2314 &CodeRate));
2315 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2316
2317 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2318 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2319 break;
2320 SignalToNoiseRel = SignalToNoise -
2321 QE_SN[Constellation * 5 + CodeRate];
2322 BERQuality = 100;
2323
2324 if (SignalToNoiseRel < -70) *pQuality = 0;
2325 else if (SignalToNoiseRel < 30)
2326 *pQuality = ((SignalToNoiseRel + 70) *
2327 BERQuality) / 100;
2328 else
2329 *pQuality = BERQuality;
2330 } while(0);
2331 return 0;
2332};
2333
2334static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
2335{
2336 int status = 0;
2337 *pQuality = 0;
2338
2339 do {
2340 u32 SignalToNoise = 0;
2341 u32 BERQuality = 100;
2342 u32 SignalToNoiseRel = 0;
2343
2344 CHK_ERROR(GetQAMSignalToNoise(state, &SignalToNoise));
2345
2346 switch(state->param.u.qam.modulation) {
2347 case QAM_16:
2348 SignalToNoiseRel = SignalToNoise - 200;
2349 break;
2350 case QAM_32:
2351 SignalToNoiseRel = SignalToNoise - 230;
2352 break; /* Not in NorDig */
2353 case QAM_64:
2354 SignalToNoiseRel = SignalToNoise - 260;
2355 break;
2356 case QAM_128:
2357 SignalToNoiseRel = SignalToNoise - 290;
2358 break;
2359 default:
2360 case QAM_256:
2361 SignalToNoiseRel = SignalToNoise - 320;
2362 break;
2363 }
2364
2365 if (SignalToNoiseRel < -70)
2366 *pQuality = 0;
2367 else if (SignalToNoiseRel < 30)
2368 *pQuality = ((SignalToNoiseRel + 70) *
2369 BERQuality) / 100;
2370 else
2371 *pQuality = BERQuality;
2372 } while(0);
2373
2374 return status;
2375}
2376
2377static int GetQuality(struct drxk_state *state, s32 *pQuality)
2378{
2379 switch(state->m_OperationMode) {
2380 case OM_DVBT:
2381 return GetDVBTQuality(state, pQuality);
2382 case OM_QAM_ITU_A:
2383 return GetDVBCQuality(state, pQuality);
2384 default:
2385 break;
2386 }
2387
2388 return 0;
2389}
2390#endif
2391
2392/* Free data ram in SIO HI */
2393#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2394#define SIO_HI_RA_RAM_USR_END__A 0x420060
2395
2396#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2397#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2398#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2399#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2400
2401#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2402#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2403#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2404
2405static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2406{
2407 int status;
2408
2409 if (state->m_DrxkState == DRXK_UNINITIALIZED)
2410 return -1;
2411 if (state->m_DrxkState == DRXK_POWERED_DOWN)
2412 return -1;
2413
2414 do {
2415 CHK_ERROR(Write16_0(state, SIO_HI_RA_RAM_PAR_1__A,
2416 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY));
2417 if (bEnableBridge) {
2418 CHK_ERROR(Write16_0(state, SIO_HI_RA_RAM_PAR_2__A,
2419 SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED));
2420 } else {
2421 CHK_ERROR(Write16_0(state, SIO_HI_RA_RAM_PAR_2__A,
2422 SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN));
2423 }
2424
2425 CHK_ERROR(HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL,0));
2426 } while(0);
2427 return status;
2428}
2429
2430static int SetPreSaw(struct drxk_state *state, struct SCfgPreSaw *pPreSawCfg)
2431{
2432 int status;
2433
2434 if ((pPreSawCfg == NULL) || (pPreSawCfg->reference>IQM_AF_PDREF__M))
2435 return -1;
2436
2437 status = Write16_0(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
2438 return status;
2439}
2440
2441static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
2442 u16 romOffset, u16 nrOfElements, u32 timeOut)
2443{
2444 u16 blStatus = 0;
2445 u16 offset = (u16)((targetAddr >> 0) & 0x00FFFF);
2446 u16 blockbank = (u16)((targetAddr >> 16) & 0x000FFF);
2447 int status ;
2448 unsigned long end;
2449
2450 mutex_lock(&state->mutex);
2451 do {
2452 CHK_ERROR(Write16_0(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT));
2453 CHK_ERROR(Write16_0(state, SIO_BL_TGT_HDR__A, blockbank));
2454 CHK_ERROR(Write16_0(state, SIO_BL_TGT_ADDR__A, offset));
2455 CHK_ERROR(Write16_0(state, SIO_BL_SRC_ADDR__A, romOffset));
2456 CHK_ERROR(Write16_0(state, SIO_BL_SRC_LEN__A, nrOfElements));
2457 CHK_ERROR(Write16_0(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON));
2458
2459 end=jiffies+msecs_to_jiffies(timeOut);
2460 do {
2461 CHK_ERROR(Read16_0(state, SIO_BL_STATUS__A, &blStatus));
2462 } while ((blStatus == 0x1) &&
2463 time_is_after_jiffies(end));
2464 if (blStatus == 0x1) {
2465 printk("SIO not ready\n");
2466 mutex_unlock(&state->mutex);
2467 return -1;
2468 }
2469 } while(0);
2470 mutex_unlock(&state->mutex);
2471 return status;
2472
2473}
2474
2475static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
2476{
2477 u16 data = 0;
2478 int status;
2479
2480 do {
2481 /* Start measurement */
2482 CHK_ERROR(Write16_0(state, IQM_AF_COMM_EXEC__A,
2483 IQM_AF_COMM_EXEC_ACTIVE));
2484 CHK_ERROR(Write16_0(state,IQM_AF_START_LOCK__A, 1));
2485
2486 *count = 0;
2487 CHK_ERROR(Read16_0(state,IQM_AF_PHASE0__A, &data));
2488 if (data == 127)
2489 *count = *count+1;
2490 CHK_ERROR(Read16_0(state,IQM_AF_PHASE1__A, &data));
2491 if (data == 127)
2492 *count = *count+1;
2493 CHK_ERROR(Read16_0(state,IQM_AF_PHASE2__A, &data));
2494 if (data == 127)
2495 *count = *count+1;
2496 } while(0);
2497 return status;
2498}
2499
2500static int ADCSynchronization(struct drxk_state *state)
2501{
2502 u16 count = 0;
2503 int status;
2504
2505 do {
2506 CHK_ERROR(ADCSyncMeasurement(state, &count));
2507
2508 if (count==1) {
2509 /* Try sampling on a diffrent edge */
2510 u16 clkNeg = 0;
2511
2512 CHK_ERROR(Read16_0(state, IQM_AF_CLKNEG__A, &clkNeg));
2513 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2514 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2515 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2516 clkNeg |=
2517 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2518 } else {
2519 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2520 clkNeg |=
2521 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2522 }
2523 CHK_ERROR(Write16_0(state, IQM_AF_CLKNEG__A, clkNeg));
2524 CHK_ERROR(ADCSyncMeasurement(state, &count));
2525 }
2526
2527 if (count < 2)
2528 status = -1;
2529 } while (0);
2530 return status;
2531}
2532
2533static int SetFrequencyShifter(struct drxk_state *state,
2534 u16 intermediateFreqkHz,
2535 s32 tunerFreqOffset,
2536 bool isDTV)
2537{
2538 bool selectPosImage = false;
2539 u32 rfFreqResidual = tunerFreqOffset;
2540 u32 fmFrequencyShift = 0;
2541 bool tunerMirror = !state->m_bMirrorFreqSpect;
2542 u32 adcFreq;
2543 bool adcFlip;
2544 int status;
2545 u32 ifFreqActual;
2546 u32 samplingFrequency = (u32)(state->m_sysClockFreq / 3);
2547 u32 frequencyShift;
2548 bool imageToSelect;
2549
2550 /*
2551 Program frequency shifter
2552 No need to account for mirroring on RF
2553 */
2554 if (isDTV) {
2555 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
2556 (state->m_OperationMode == OM_QAM_ITU_C) ||
2557 (state->m_OperationMode == OM_DVBT))
2558 selectPosImage = true;
2559 else
2560 selectPosImage = false;
2561 }
2562 if (tunerMirror)
2563 /* tuner doesn't mirror */
2564 ifFreqActual = intermediateFreqkHz +
2565 rfFreqResidual + fmFrequencyShift;
2566 else
2567 /* tuner mirrors */
2568 ifFreqActual = intermediateFreqkHz -
2569 rfFreqResidual - fmFrequencyShift;
2570 if (ifFreqActual > samplingFrequency / 2) {
2571 /* adc mirrors */
2572 adcFreq = samplingFrequency - ifFreqActual;
2573 adcFlip = true;
2574 } else {
2575 /* adc doesn't mirror */
2576 adcFreq = ifFreqActual;
2577 adcFlip = false;
2578 }
2579
2580 frequencyShift = adcFreq;
2581 imageToSelect = state->m_rfmirror ^ tunerMirror ^
2582 adcFlip ^ selectPosImage;
2583 state->m_IqmFsRateOfs = Frac28a((frequencyShift), samplingFrequency);
2584
2585 if (imageToSelect)
2586 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
2587
2588 /* Program frequency shifter with tuner offset compensation */
2589 /* frequencyShift += tunerFreqOffset; TODO */
2590 status = Write32(state, IQM_FS_RATE_OFS_LO__A ,
2591 state->m_IqmFsRateOfs, 0);
2592 return status;
2593}
2594
2595static int InitAGC(struct drxk_state *state, bool isDTV)
2596{
2597 u16 ingainTgt = 0;
2598 u16 ingainTgtMin = 0;
2599 u16 ingainTgtMax = 0;
2600 u16 clpCyclen = 0;
2601 u16 clpSumMin = 0;
2602 u16 clpDirTo = 0;
2603 u16 snsSumMin = 0;
2604 u16 snsSumMax = 0;
2605 u16 clpSumMax = 0;
2606 u16 snsDirTo = 0;
2607 u16 kiInnergainMin = 0;
2608 u16 ifIaccuHiTgt = 0;
2609 u16 ifIaccuHiTgtMin = 0;
2610 u16 ifIaccuHiTgtMax = 0;
2611 u16 data = 0;
2612 u16 fastClpCtrlDelay = 0;
2613 u16 clpCtrlMode = 0;
2614 int status = 0;
2615
2616 do {
2617 /* Common settings */
2618 snsSumMax = 1023;
2619 ifIaccuHiTgtMin = 2047;
2620 clpCyclen = 500;
2621 clpSumMax = 1023;
2622
2623 if (IsQAM(state)) {
2624 /* Standard specific settings */
2625 clpSumMin = 8;
2626 clpDirTo = (u16) - 9;
2627 clpCtrlMode = 0;
2628 snsSumMin = 8;
2629 snsDirTo = (u16) - 9;
2630 kiInnergainMin = (u16) - 1030;
2631 } else
2632 status = -1;
2633 CHK_ERROR((status));
2634 if (IsQAM(state)) {
2635 ifIaccuHiTgtMax = 0x2380;
2636 ifIaccuHiTgt = 0x2380;
2637 ingainTgtMin = 0x0511;
2638 ingainTgt = 0x0511;
2639 ingainTgtMax = 5119;
2640 fastClpCtrlDelay =
2641 state->m_qamIfAgcCfg.FastClipCtrlDelay;
2642 } else {
2643 ifIaccuHiTgtMax = 0x1200;
2644 ifIaccuHiTgt = 0x1200;
2645 ingainTgtMin = 13424;
2646 ingainTgt = 13424;
2647 ingainTgtMax = 30000;
2648 fastClpCtrlDelay =
2649 state->m_dvbtIfAgcCfg.FastClipCtrlDelay;
2650 }
2651 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
2652 fastClpCtrlDelay));
2653
2654 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_CLP_CTRL_MODE__A,
2655 clpCtrlMode));
2656 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_INGAIN_TGT__A,
2657 ingainTgt));
2658 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
2659 ingainTgtMin));
2660 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A,
2661 ingainTgtMax));
2662 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A,
2663 ifIaccuHiTgtMin));
2664 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2665 ifIaccuHiTgtMax));
2666 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0));
2667 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0));
2668 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0));
2669 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0));
2670 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_CLP_SUM_MAX__A,
2671 clpSumMax));
2672 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_SNS_SUM_MAX__A,
2673 snsSumMax));
2674
2675 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A,
2676 kiInnergainMin));
2677 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
2678 ifIaccuHiTgt));
2679 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_CLP_CYCLEN__A,
2680 clpCyclen));
2681
2682 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A,
2683 1023));
2684 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A,
2685 (u16) -1023));
2686 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A,
2687 50));
2688
2689 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A,
2690 20));
2691 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_CLP_SUM_MIN__A,
2692 clpSumMin));
2693 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_SNS_SUM_MIN__A,
2694 snsSumMin));
2695 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_CLP_DIR_TO__A,
2696 clpDirTo));
2697 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_SNS_DIR_TO__A,
2698 snsDirTo));
2699 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff));
2700 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0));
2701 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_KI_MIN__A, 0x0117));
2702 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_KI_MAX__A, 0x0657));
2703 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_CLP_SUM__A, 0));
2704 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0));
2705 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0));
2706 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1));
2707 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_SNS_SUM__A, 0));
2708 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0));
2709 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0));
2710 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1));
2711 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500));
2712 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_KI_CYCLEN__A, 500));
2713
2714 /* Initialize inner-loop KI gain factors */
2715 CHK_ERROR(Read16_0(state, SCU_RAM_AGC_KI__A, &data));
2716 if (IsQAM(state)) {
2717 data = 0x0657;
2718 data &= ~SCU_RAM_AGC_KI_RF__M;
2719 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
2720 data &= ~SCU_RAM_AGC_KI_IF__M;
2721 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
2722 }
2723 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_KI__A, data));
2724 } while(0);
2725 return status;
2726}
2727
2728static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 * packetErr)
2729{
2730 int status;
2731
2732 do {
2733 if (packetErr == NULL) {
2734 CHK_ERROR(Write16_0(state,
2735 SCU_RAM_FEC_ACCUM_PKT_FAILURES__A,
2736 0));
2737 } else {
2738 CHK_ERROR(Read16_0(state,
2739 SCU_RAM_FEC_ACCUM_PKT_FAILURES__A,
2740 packetErr));
2741 }
2742 } while (0);
2743 return status;
2744}
2745
2746static int DVBTScCommand(struct drxk_state *state,
2747 u16 cmd, u16 subcmd,
2748 u16 param0, u16 param1, u16 param2,
2749 u16 param3, u16 param4)
2750{
2751 u16 curCmd = 0;
2752 u16 errCode = 0;
2753 u16 retryCnt = 0;
2754 u16 scExec = 0;
2755 int status;
2756
2757 status = Read16_0(state, OFDM_SC_COMM_EXEC__A, &scExec);
2758 if (scExec != 1) {
2759 /* SC is not running */
2760 return -1;
2761 }
2762
2763 /* Wait until sc is ready to receive command */
2764 retryCnt =0;
2765 do {
2766 msleep(1);
2767 status = Read16_0(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
2768 retryCnt++;
2769 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
2770 if (retryCnt >= DRXK_MAX_RETRIES)
2771 return -1;
2772 /* Write sub-command */
2773 switch (cmd) {
2774 /* All commands using sub-cmd */
2775 case OFDM_SC_RA_RAM_CMD_PROC_START:
2776 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
2777 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
2778 status = Write16_0(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
2779 break;
2780 default:
2781 /* Do nothing */
2782 break;
2783 } /* switch (cmd->cmd) */
2784
2785 /* Write needed parameters and the command */
2786 switch (cmd) {
2787 /* All commands using 5 parameters */
2788 /* All commands using 4 parameters */
2789 /* All commands using 3 parameters */
2790 /* All commands using 2 parameters */
2791 case OFDM_SC_RA_RAM_CMD_PROC_START:
2792 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
2793 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
2794 status = Write16_0(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
2795 /* All commands using 1 parameters */
2796 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
2797 case OFDM_SC_RA_RAM_CMD_USER_IO:
2798 status = Write16_0(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
2799 /* All commands using 0 parameters */
2800 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
2801 case OFDM_SC_RA_RAM_CMD_NULL:
2802 /* Write command */
2803 status = Write16_0(state, OFDM_SC_RA_RAM_CMD__A, cmd);
2804 break;
2805 default:
2806 /* Unknown command */
2807 return -EINVAL;
2808 } /* switch (cmd->cmd) */
2809
2810 /* Wait until sc is ready processing command */
2811 retryCnt = 0;
2812 do{
2813 msleep(1);
2814 status = Read16_0(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
2815 retryCnt++;
2816 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
2817 if (retryCnt >= DRXK_MAX_RETRIES)
2818 return -1;
2819
2820 /* Check for illegal cmd */
2821 status = Read16_0(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
2822 if (errCode == 0xFFFF)
2823 {
2824 /* illegal command */
2825 return -EINVAL;
2826 }
2827
2828 /* Retreive results parameters from SC */
2829 switch (cmd) {
2830 /* All commands yielding 5 results */
2831 /* All commands yielding 4 results */
2832 /* All commands yielding 3 results */
2833 /* All commands yielding 2 results */
2834 /* All commands yielding 1 result */
2835 case OFDM_SC_RA_RAM_CMD_USER_IO:
2836 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
2837 status = Read16_0(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
2838 /* All commands yielding 0 results */
2839 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
2840 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
2841 case OFDM_SC_RA_RAM_CMD_PROC_START:
2842 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
2843 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
2844 case OFDM_SC_RA_RAM_CMD_NULL:
2845 break;
2846 default:
2847 /* Unknown command */
2848 return -EINVAL;
2849 break;
2850 } /* switch (cmd->cmd) */
2851 return status;
2852}
2853
2854static int PowerUpDVBT (struct drxk_state *state)
2855{
2856 DRXPowerMode_t powerMode = DRX_POWER_UP;
2857 int status;
2858
2859 do {
2860 CHK_ERROR(CtrlPowerMode(state, &powerMode));
2861 } while (0);
2862 return status;
2863}
2864
2865static int DVBTCtrlSetIncEnable (struct drxk_state *state, bool* enabled)
2866{
2867 int status;
2868 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
2869 if (*enabled == true)
2870 {
2871 status = Write16_0(state, IQM_CF_BYPASSDET__A, 0);
2872 }
2873 else
2874 {
2875 status = Write16_0(state, IQM_CF_BYPASSDET__A, 1);
2876 }
2877 if (status<0)
2878 {
2879 //KdPrintEx((MSG_ERROR " - " __FUNCTION__ " status - %08x\n",status));
2880 }
2881
2882 return status;
2883}
2884 #define DEFAULT_FR_THRES_8K 4000
2885static int DVBTCtrlSetFrEnable (struct drxk_state *state, bool* enabled)
2886{
2887
2888 int status;
2889 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
2890
2891 if (*enabled == true)
2892 {
2893 /* write mask to 1 */
2894 status = Write16_0(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
2895 DEFAULT_FR_THRES_8K);
2896 }
2897 else
2898 {
2899 /* write mask to 0 */
2900 status = Write16_0(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
2901 }
2902
2903 if (status<0)
2904 {
2905 //KdPrintEx((MSG_ERROR " - " __FUNCTION__ " status - %08x\n",status));
2906 }
2907
2908 return status;
2909}
2910
2911static int DVBTCtrlSetEchoThreshold (struct drxk_state *state,
2912 struct DRXKCfgDvbtEchoThres_t* echoThres)
2913{
2914 u16 data = 0;
2915 int status;
2916 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
2917
2918 do {
2919 CHK_ERROR(Read16_0(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data));
2920
2921 switch (echoThres->fftMode)
2922 {
2923 case DRX_FFTMODE_2K:
2924 data &= ~ OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
2925 data |= ((echoThres->threshold << OFDM_SC_RA_RAM_ECHO_THRES_2K__B) &
2926 (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
2927 break;
2928 case DRX_FFTMODE_8K:
2929 data &= ~ OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
2930 data |= ((echoThres->threshold << OFDM_SC_RA_RAM_ECHO_THRES_8K__B) &
2931 (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
2932 break;
2933 default:
2934 return -1;
2935 break;
2936 }
2937
2938 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data));
2939 } while (0);
2940
2941 if (status<0)
2942 {
2943 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ " status - %08x\n",status));
2944 }
2945
2946 return status;
2947}
2948
2949static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
2950 enum DRXKCfgDvbtSqiSpeed* speed)
2951{
2952 int status;
2953
2954 switch (*speed) {
2955 case DRXK_DVBT_SQI_SPEED_FAST:
2956 case DRXK_DVBT_SQI_SPEED_MEDIUM:
2957 case DRXK_DVBT_SQI_SPEED_SLOW:
2958 break;
2959 default:
2960 return -EINVAL;
2961 }
2962 status = Write16_0 (state,SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
2963 (u16) *speed);
2964 return status;
2965}
2966
2967/*============================================================================*/
2968
2969/**
2970* \brief Activate DVBT specific presets
2971* \param demod instance of demodulator.
2972* \return DRXStatus_t.
2973*
2974* Called in DVBTSetStandard
2975*
2976*/
2977static int DVBTActivatePresets (struct drxk_state *state)
2978{
2979 int status;
2980
2981 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
2982
2983 struct DRXKCfgDvbtEchoThres_t echoThres2k = {0, DRX_FFTMODE_2K};
2984 struct DRXKCfgDvbtEchoThres_t echoThres8k = {0, DRX_FFTMODE_8K};
2985
2986 do {
2987 bool setincenable = false;
2988 bool setfrenable = true;
2989 CHK_ERROR(DVBTCtrlSetIncEnable (state, &setincenable));
2990 CHK_ERROR(DVBTCtrlSetFrEnable (state, &setfrenable));
2991 CHK_ERROR(DVBTCtrlSetEchoThreshold(state, &echoThres2k));
2992 CHK_ERROR(DVBTCtrlSetEchoThreshold(state, &echoThres8k));
2993 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A,
2994 state->m_dvbtIfAgcCfg.IngainTgtMax));
2995 } while (0);
2996
2997 if (status<0)
2998 {
2999 //KdPrintEx((MSG_ERROR " - " __FUNCTION__ " status - %08x\n",status));
3000 }
3001
3002 return status;
3003}
3004/*============================================================================*/
3005
3006/**
3007* \brief Initialize channelswitch-independent settings for DVBT.
3008* \param demod instance of demodulator.
3009* \return DRXStatus_t.
3010*
3011* For ROM code channel filter taps are loaded from the bootloader. For microcode
3012* the DVB-T taps from the drxk_filters.h are used.
3013*/
3014static int SetDVBTStandard (struct drxk_state *state,enum OperationMode oMode)
3015{
3016 u16 cmdResult = 0;
3017 u16 data = 0;
3018 int status;
3019
3020 //printk("%s\n", __FUNCTION__);
3021
3022 PowerUpDVBT(state);
3023
3024 do {
3025 /* added antenna switch */
3026 SwitchAntennaToDVBT(state);
3027 /* send OFDM reset command */
3028 CHK_ERROR(scu_command(state,SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET,0,NULL,1,&cmdResult));
3029
3030 /* send OFDM setenv command */
3031 CHK_ERROR(scu_command(state,SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,0,NULL,1,&cmdResult));
3032
3033 /* reset datapath for OFDM, processors first */
3034 CHK_ERROR(Write16_0(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP));
3035 CHK_ERROR(Write16_0(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP));
3036 CHK_ERROR(Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP ));
3037
3038 /* IQM setup */
3039 /* synchronize on ofdstate->m_festart */
3040 CHK_ERROR(Write16_0(state, IQM_AF_UPD_SEL__A, 1));
3041 /* window size for clipping ADC detection */
3042 CHK_ERROR(Write16_0(state, IQM_AF_CLP_LEN__A, 0));
3043 /* window size for for sense pre-SAW detection */
3044 CHK_ERROR(Write16_0(state, IQM_AF_SNS_LEN__A, 0));
3045 /* sense threshold for sense pre-SAW detection */
3046 CHK_ERROR(Write16_0(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC));
3047 CHK_ERROR(SetIqmAf(state,true));
3048
3049 CHK_ERROR(Write16_0(state, IQM_AF_AGC_RF__A, 0));
3050
3051 /* Impulse noise cruncher setup */
3052 CHK_ERROR(Write16_0(state, IQM_AF_INC_LCT__A, 0)); /* crunch in IQM_CF */
3053 CHK_ERROR(Write16_0(state, IQM_CF_DET_LCT__A, 0)); /* detect in IQM_CF */
3054 CHK_ERROR(Write16_0(state, IQM_CF_WND_LEN__A, 3)); /* peak detector window length */
3055
3056 CHK_ERROR(Write16_0(state, IQM_RC_STRETCH__A, 16));
3057 CHK_ERROR(Write16_0(state, IQM_CF_OUT_ENA__A, 0x4)); /* enable output 2 */
3058 CHK_ERROR(Write16_0(state, IQM_CF_DS_ENA__A, 0x4)); /* decimate output 2 */
3059 CHK_ERROR(Write16_0(state, IQM_CF_SCALE__A, 1600));
3060 CHK_ERROR(Write16_0(state, IQM_CF_SCALE_SH__A, 0));
3061
3062 /* virtual clipping threshold for clipping ADC detection */
3063 CHK_ERROR(Write16_0(state, IQM_AF_CLP_TH__A, 448));
3064 CHK_ERROR(Write16_0(state, IQM_CF_DATATH__A, 495)); /* crunching threshold */
3065
3066 CHK_ERROR(BLChainCmd(state,
3067 DRXK_BL_ROM_OFFSET_TAPS_DVBT,
3068 DRXK_BLCC_NR_ELEMENTS_TAPS,
3069 DRXK_BLC_TIMEOUT));
3070
3071 CHK_ERROR(Write16_0(state, IQM_CF_PKDTH__A, 2)); /* peak detector threshold */
3072 CHK_ERROR(Write16_0(state, IQM_CF_POW_MEAS_LEN__A, 2));
3073 /* enable power measurement interrupt */
3074 CHK_ERROR(Write16_0(state, IQM_CF_COMM_INT_MSK__A, 1));
3075 CHK_ERROR(Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE));
3076
3077 /* IQM will not be reset from here, sync ADC and update/init AGC */
3078 CHK_ERROR(ADCSynchronization(state));
3079 CHK_ERROR(SetPreSaw(state, &state->m_dvbtPreSawCfg));
3080
3081 /* Halt SCU to enable safe non-atomic accesses */
3082 CHK_ERROR(Write16_0(state,SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD));
3083
3084 CHK_ERROR(SetAgcRf(state, &state->m_dvbtRfAgcCfg, true)) ;
3085 CHK_ERROR(SetAgcIf (state, &state->m_dvbtIfAgcCfg, true));
3086
3087 /* Set Noise Estimation notch width and enable DC fix */
3088 CHK_ERROR(Read16_0(state, OFDM_SC_RA_RAM_CONFIG__A, &data));
3089 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3090 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_CONFIG__A, data));
3091
3092 /* Activate SCU to enable SCU commands */
3093 CHK_ERROR(Write16_0(state,SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE));
3094
3095 if (!state->m_DRXK_A3_ROM_CODE)
3096 {
3097 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3098 CHK_ERROR(Write16_0(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
3099 state->m_dvbtIfAgcCfg.FastClipCtrlDelay));
3100 }
3101
3102 /* OFDM_SC setup */
3103#ifdef COMPILE_FOR_NONRT
3104 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1));
3105 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2));
3106#endif
3107
3108 /* FEC setup */
3109 CHK_ERROR(Write16_0(state, FEC_DI_INPUT_CTL__A, 1)); /* OFDM input */
3110
3111
3112#ifdef COMPILE_FOR_NONRT
3113 CHK_ERROR(Write16_0(state, FEC_RS_MEASUREMENT_PERIOD__A , 0x400));
3114#else
3115 CHK_ERROR(Write16_0(state, FEC_RS_MEASUREMENT_PERIOD__A , 0x1000));
3116#endif
3117 CHK_ERROR(Write16_0(state, FEC_RS_MEASUREMENT_PRESCALE__A , 0x0001));
3118
3119 /* Setup MPEG bus */
3120 CHK_ERROR(MPEGTSDtoSetup (state,OM_DVBT));
3121 /* Set DVBT Presets */
3122 CHK_ERROR (DVBTActivatePresets (state));
3123
3124 } while (0);
3125
3126 if (status<0)
3127 {
3128 printk("%s status - %08x\n",__FUNCTION__,status);
3129 }
3130
3131 return status;
3132}
3133
3134/*============================================================================*/
3135/**
3136* \brief Start dvbt demodulating for channel.
3137* \param demod instance of demodulator.
3138* \return DRXStatus_t.
3139*/
3140static int DVBTStart(struct drxk_state *state)
3141{
3142 u16 param1;
3143
3144 int status;
3145// DRXKOfdmScCmd_t scCmd;
3146
3147 //printk("%s\n",__FUNCTION__);
3148 /* Start correct processes to get in lock */
3149 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
3150 do {
3151 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3152 CHK_ERROR(DVBTScCommand(state,OFDM_SC_RA_RAM_CMD_PROC_START,0,OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M,param1,0,0,0));
3153 /* Start FEC OC */
3154 CHK_ERROR(MPEGTSStart(state));
3155 CHK_ERROR(Write16_0(state,FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE));
3156 } while (0);
3157 return (status);
3158}
3159
3160
3161/*============================================================================*/
3162
3163/**
3164* \brief Set up dvbt demodulator for channel.
3165* \param demod instance of demodulator.
3166* \return DRXStatus_t.
3167* // original DVBTSetChannel()
3168*/
3169static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerFreqOffset)
3170{
3171 u16 cmdResult = 0;
3172 u16 transmissionParams = 0;
3173 u16 operationMode = 0;
3174 u32 iqmRcRateOfs = 0;
3175 u32 bandwidth = 0;
3176 u16 param1;
3177 int status;
3178
3179 //printk("%s IF =%d, TFO = %d\n",__FUNCTION__,IntermediateFreqkHz,tunerFreqOffset);
3180 do {
3181 CHK_ERROR(scu_command(state,SCU_RAM_COMMAND_STANDARD_OFDM |
3182 SCU_RAM_COMMAND_CMD_DEMOD_STOP,
3183 0,NULL,1,&cmdResult));
3184
3185 /* Halt SCU to enable safe non-atomic accesses */
3186 CHK_ERROR(Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD));
3187
3188 /* Stop processors */
3189 CHK_ERROR(Write16_0(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP));
3190 CHK_ERROR(Write16_0(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP));
3191
3192 /* Mandatory fix, always stop CP, required to set spl offset back to
3193 hardware default (is set to 0 by ucode during pilot detection */
3194 CHK_ERROR(Write16_0(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP));
3195
3196 /*== Write channel settings to device =====================================*/
3197
3198 /* mode */
3199 switch(state->param.u.ofdm.transmission_mode) {
3200 case TRANSMISSION_MODE_AUTO:
3201 default:
3202 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3203 /* fall through , try first guess DRX_FFTMODE_8K */
3204 case TRANSMISSION_MODE_8K:
3205 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
3206 break;
3207 case TRANSMISSION_MODE_2K:
3208 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
3209 break;
3210 }
3211
3212 /* guard */
3213 switch(state->param.u.ofdm.guard_interval) {
3214 default:
3215 case GUARD_INTERVAL_AUTO:
3216 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3217 /* fall through , try first guess DRX_GUARD_1DIV4 */
3218 case GUARD_INTERVAL_1_4:
3219 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
3220 break;
3221 case GUARD_INTERVAL_1_32:
3222 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
3223 break;
3224 case GUARD_INTERVAL_1_16:
3225 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
3226 break;
3227 case GUARD_INTERVAL_1_8:
3228 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
3229 break;
3230 }
3231
3232 /* hierarchy */
3233 switch(state->param.u.ofdm.hierarchy_information) {
3234 case HIERARCHY_AUTO:
3235 case HIERARCHY_NONE:
3236 default:
3237 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3238 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3239 // transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO;
3240 //break;
3241 case HIERARCHY_1:
3242 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3243 break;
3244 case HIERARCHY_2:
3245 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3246 break;
3247 case HIERARCHY_4:
3248 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3249 break;
3250 }
3251
3252
3253 /* constellation */
3254 switch(state->param.u.ofdm.constellation) {
3255 case QAM_AUTO:
3256 default:
3257 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3258 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3259 case QAM_64:
3260 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3261 break;
3262 case QPSK:
3263 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3264 break;
3265 case QAM_16:
3266 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3267 break;
3268 }
3269#if 0
3270 // No hierachical channels support in BDA
3271 /* Priority (only for hierarchical channels) */
3272 switch (channel->priority) {
3273 case DRX_PRIORITY_LOW :
3274 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3275 WR16(devAddr, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_LO);
3276 break;
3277 case DRX_PRIORITY_HIGH :
3278 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3279 WR16(devAddr, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI));
3280 break;
3281 case DRX_PRIORITY_UNKNOWN : /* fall through */
3282 default:
3283 return (DRX_STS_INVALID_ARG);
3284 break;
3285 }
3286#else
3287 // Set Priorty high
3288 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3289 CHK_ERROR(Write16_0(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI));
3290#endif
3291
3292 /* coderate */
3293 switch(state->param.u.ofdm.code_rate_HP) {
3294 case FEC_AUTO:
3295 default:
3296 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3297 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3298 case FEC_2_3 :
3299 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3300 break;
3301 case FEC_1_2 :
3302 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3303 break;
3304 case FEC_3_4 :
3305 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3306 break;
3307 case FEC_5_6 :
3308 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3309 break;
3310 case FEC_7_8 :
3311 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3312 break;
3313 }
3314
3315 /* SAW filter selection: normaly not necesarry, but if wanted
3316 the application can select a SAW filter via the driver by using UIOs */
3317 /* First determine real bandwidth (Hz) */
3318 /* Also set delay for impulse noise cruncher */
3319 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3320 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3321 functions */
3322 switch(state->param.u.ofdm.bandwidth) {
3323 case BANDWIDTH_AUTO:
3324 case BANDWIDTH_8_MHZ:
3325 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3326 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052));
3327 /* cochannel protection for PAL 8 MHz */
3328 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7));
3329 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7));
3330 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7));
3331 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1));
3332 break;
3333 case BANDWIDTH_7_MHZ:
3334 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3335 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491));
3336 /* cochannel protection for PAL 7 MHz */
3337 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8));
3338 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8));
3339 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4));
3340 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1));
3341 break;
3342 case BANDWIDTH_6_MHZ:
3343 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3344 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073));
3345 /* cochannel protection for NTSC 6 MHz */
3346 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19));
3347 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19));
3348 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14));
3349 CHK_ERROR(Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1));
3350 break;
3351 }
3352
3353 if (iqmRcRateOfs == 0)
3354 {
3355 /* Now compute IQM_RC_RATE_OFS
3356 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3357 =>
3358 ((SysFreq / BandWidth) * (2^21)) - (2^23)
3359 */
3360 /* (SysFreq / BandWidth) * (2^28) */
3361 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
3362 => assert(MAX(sysClk) < 16*MIN(bandwidth))
3363 => assert(109714272 > 48000000) = true so Frac 28 can be used */
3364 iqmRcRateOfs = Frac28a((u32)((state->m_sysClockFreq * 1000)/3), bandwidth);
3365 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
3366 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
3367 {
3368 iqmRcRateOfs += 0x80L;
3369 }
3370 iqmRcRateOfs = iqmRcRateOfs >> 7 ;
3371 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
3372 iqmRcRateOfs = iqmRcRateOfs - (1<<23);
3373 }
3374
3375 iqmRcRateOfs &= ((((u32)IQM_RC_RATE_OFS_HI__M)<<IQM_RC_RATE_OFS_LO__W) |
3376 IQM_RC_RATE_OFS_LO__M);
3377 CHK_ERROR(Write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs,0));
3378
3379 /* Bandwidth setting done */
3380
3381 // CHK_ERROR(DVBTSetFrequencyShift(demod, channel, tunerOffset));
3382 CHK_ERROR (SetFrequencyShifter (state, IntermediateFreqkHz, tunerFreqOffset, true));
3383
3384 /*== Start SC, write channel settings to SC ===============================*/
3385
3386 /* Activate SCU to enable SCU commands */
3387 CHK_ERROR(Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE));
3388
3389 /* Enable SC after setting all other parameters */
3390 CHK_ERROR(Write16_0(state, OFDM_SC_COMM_STATE__A, 0));
3391 CHK_ERROR(Write16_0(state, OFDM_SC_COMM_EXEC__A, 1));
3392
3393
3394 CHK_ERROR(scu_command(state,SCU_RAM_COMMAND_STANDARD_OFDM |
3395 SCU_RAM_COMMAND_CMD_DEMOD_START,0,NULL,1,&cmdResult));
3396
3397 /* Write SC parameter registers, set all AUTO flags in operation mode */
3398 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
3399 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
3400 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
3401 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
3402 OFDM_SC_RA_RAM_OP_AUTO_RATE__M );
3403 status = DVBTScCommand(state,OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,0,transmissionParams,param1,0,0,0);
3404 if (!state->m_DRXK_A3_ROM_CODE)
3405 CHK_ERROR (DVBTCtrlSetSqiSpeed(state,&state->m_sqiSpeed));
3406
3407 } while(0);
3408 if (status<0) {
3409 //printk("%s status - %08x\n",__FUNCTION__,status);
3410 }
3411
3412 return status;
3413}
3414
3415
3416/*============================================================================*/
3417
3418/**
3419* \brief Retreive lock status .
3420* \param demod Pointer to demodulator instance.
3421* \param lockStat Pointer to lock status structure.
3422* \return DRXStatus_t.
3423*
3424*/
3425static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
3426{
3427 int status;
3428 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
3429 OFDM_SC_RA_RAM_LOCK_FEC__M );
3430 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
3431 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M ;
3432
3433 u16 ScRaRamLock = 0;
3434 u16 ScCommExec = 0;
3435
3436 /* driver 0.9.0 */
3437 /* Check if SC is running */
3438 status = Read16_0(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
3439 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
3440 {
3441 /* SC not active; return DRX_NOT_LOCKED */
3442 *pLockStatus = NOT_LOCKED;
3443 return status;
3444 }
3445
3446 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
3447
3448 status = Read16_0(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
3449
3450 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "RamLock: %04X\n",ScRaRamLock));
3451
3452 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask) {
3453 *pLockStatus = MPEG_LOCK;
3454 } else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask) {
3455 *pLockStatus = FEC_LOCK;
3456 } else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask) {
3457 *pLockStatus = DEMOD_LOCK;
3458 } else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M) {
3459 *pLockStatus = NEVER_LOCK;
3460 } else {
3461 *pLockStatus = NOT_LOCKED;
3462 }
3463
3464 if (status<0)
3465 {
3466 //KdPrintEx((MSG_ERROR " - " __FUNCTION__ " status - %08x\n",status));
3467 }
3468
3469 return status;
3470}
3471
3472static int PowerUpQAM (struct drxk_state *state)
3473{
3474 DRXPowerMode_t powerMode = DRXK_POWER_DOWN_OFDM;
3475
3476
3477 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
3478 int status = 0;
3479 do
3480 {
3481 CHK_ERROR(CtrlPowerMode(state, &powerMode));
3482
3483 }while(0);
3484
3485 if (status<0)
3486 {
3487 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ " status - %08x\n",status));
3488 }
3489 return status;
3490}
3491
3492
3493/// Power Down QAM
3494static int PowerDownQAM(struct drxk_state *state)
3495{
3496 u16 data = 0;
3497 u16 cmdResult;
3498
3499 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
3500 int status = 0;
3501 do
3502 {
3503 CHK_ERROR(Read16_0(state, SCU_COMM_EXEC__A, &data));
3504 if (data == SCU_COMM_EXEC_ACTIVE)
3505 {
3506 /*
3507 STOP demodulator
3508 QAM and HW blocks
3509 */
3510 /* stop all comstate->m_exec */
3511 CHK_ERROR(Write16_0(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP));
3512 CHK_ERROR(scu_command(state,SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP,0,NULL,1,&cmdResult));
3513 }
3514 /* powerdown AFE */
3515 CHK_ERROR(SetIqmAf(state, false));
3516 }
3517 while(0);
3518
3519 if (status<0)
3520 {
3521 //KdPrintEx((MSG_ERROR " - " __FUNCTION__ " status - %08x\n",status));
3522 }
3523 return status;
3524}
3525/*============================================================================*/
3526
3527/**
3528* \brief Setup of the QAM Measurement intervals for signal quality
3529* \param demod instance of demod.
3530* \param constellation current constellation.
3531* \return DRXStatus_t.
3532*
3533* NOTE:
3534* Take into account that for certain settings the errorcounters can overflow.
3535* The implementation does not check this.
3536*
3537*/
3538static int SetQAMMeasurement(struct drxk_state *state,
3539 enum EDrxkConstellation constellation,
3540 u32 symbolRate)
3541{
3542 //KdPrintEx((MSG_ERROR " - " __FUNCTION__ "(%d,%d) om = %d\n", constellation, symbolRate,state->m_OperationMode));
3543
3544 u32 fecBitsDesired = 0; /* BER accounting period */
3545 u32 fecRsPeriodTotal = 0; /* Total period */
3546 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
3547 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
3548 int status = 0;
3549
3550 fecRsPrescale = 1;
3551
3552 do {
3553
3554 /* fecBitsDesired = symbolRate [kHz] *
3555 FrameLenght [ms] *
3556 (constellation + 1) *
3557 SyncLoss (== 1) *
3558 ViterbiLoss (==1)
3559 */
3560 switch (constellation)
3561 {
3562 case DRX_CONSTELLATION_QAM16:
3563 fecBitsDesired = 4 * symbolRate;
3564 break;
3565 case DRX_CONSTELLATION_QAM32:
3566 fecBitsDesired = 5 * symbolRate;
3567 break;
3568 case DRX_CONSTELLATION_QAM64:
3569 fecBitsDesired = 6 * symbolRate;
3570 break;
3571 case DRX_CONSTELLATION_QAM128:
3572 fecBitsDesired = 7 * symbolRate;
3573 break;
3574 case DRX_CONSTELLATION_QAM256:
3575 fecBitsDesired = 8 * symbolRate;
3576 break;
3577 default:
3578 status = -EINVAL;
3579 }
3580 CHK_ERROR(status);
3581
3582 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
3583 fecBitsDesired *= 500; /* meas. period [ms] */
3584
3585 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
3586 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
3587 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil*/
3588
3589 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
3590 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
3591 if (fecRsPrescale == 0) {
3592 /* Divide by zero (though impossible) */
3593 status = -1;
3594 }
3595 CHK_ERROR(status);
3596 fecRsPeriod = ((u16) fecRsPeriodTotal + (fecRsPrescale >> 1)) /
3597 fecRsPrescale;
3598
3599 /* write corresponding registers */
3600 CHK_ERROR(Write16_0(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod));
3601 CHK_ERROR(Write16_0(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale));
3602 CHK_ERROR(Write16_0(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod));
3603
3604 } while (0);
3605
3606 if (status<0) {
3607 printk("%s: status - %08x\n",__FUNCTION__,status);
3608 }
3609 return status;
3610}
3611
3612static int SetQAM16 (struct drxk_state *state)
3613{
3614 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
3615 int status = 0;
3616 do
3617 {
3618 /* QAM Equalizer Setup */
3619 /* Equalizer */
3620 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517));
3621 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517));
3622 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517));
3623 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517));
3624 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517));
3625 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517));
3626 /* Decision Feedback Equalizer */
3627 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN0__A, 2));
3628 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN1__A, 2));
3629 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN2__A, 2));
3630 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN3__A, 2));
3631 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN4__A, 2));
3632 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0));
3633
3634 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_HWM__A, 5));
3635 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_AWM__A, 4));
3636 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_LWM__A, 3));
3637
3638 /* QAM Slicer Settings */
3639 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16));
3640
3641 /* QAM Loop Controller Coeficients */
3642 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15));
3643 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40));
3644 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12));
3645 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24));
3646 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24));
3647 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12));
3648 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16));
3649 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16));
3650
3651 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5));
3652 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20));
3653 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80));
3654 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5));
3655 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20));
3656 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50));
3657 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16));
3658 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16));
3659 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32));
3660 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5));
3661 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10));
3662 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10));
3663
3664
3665 /* QAM State Machine (FSM) Thresholds */
3666
3667 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 140));
3668 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 50));
3669 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 95));
3670 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 120));
3671 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 230));
3672 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 105));
3673
3674 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40));
3675 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4));
3676 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24));
3677
3678
3679 /* QAM FSM Tracking Parameters */
3680
3681 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16));
3682 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220));
3683 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25));
3684 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6));
3685 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24));
3686 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65));
3687 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)-127));
3688 }while(0);
3689
3690 if (status<0)
3691 {
3692 //KdPrintEx((MSG_ERROR " - " __FUNCTION__ " status - %08x\n",status));
3693 }
3694 return status;
3695}
3696
3697/*============================================================================*/
3698
3699/**
3700* \brief QAM32 specific setup
3701* \param demod instance of demod.
3702* \return DRXStatus_t.
3703*/
3704static int SetQAM32 (struct drxk_state *state)
3705{
3706 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
3707 int status = 0;
3708 do
3709 {
3710 /* QAM Equalizer Setup */
3711 /* Equalizer */
3712 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707));
3713 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707));
3714 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707));
3715 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707));
3716 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707));
3717 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707));
3718
3719 /* Decision Feedback Equalizer */
3720 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN0__A, 3));
3721 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN1__A, 3));
3722 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN2__A, 3));
3723 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN3__A, 3));
3724 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN4__A, 3));
3725 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0));
3726
3727 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_HWM__A, 6));
3728 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_AWM__A, 5));
3729 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_LWM__A, 3));
3730
3731 /* QAM Slicer Settings */
3732
3733 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32));
3734
3735
3736 /* QAM Loop Controller Coeficients */
3737
3738 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15));
3739 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40));
3740 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12));
3741 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24));
3742 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24));
3743 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12));
3744 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16));
3745 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16));
3746
3747 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5));
3748 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20));
3749 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80));
3750 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5));
3751 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20));
3752 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50));
3753 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16));
3754 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16));
3755 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16));
3756 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5));
3757 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10));
3758 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0));
3759
3760
3761 /* QAM State Machine (FSM) Thresholds */
3762
3763 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 90));
3764 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 50));
3765 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80));
3766 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 100));
3767 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 170));
3768 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 100));
3769
3770 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40));
3771 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4));
3772 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10));
3773
3774
3775 /* QAM FSM Tracking Parameters */
3776
3777 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12));
3778 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140));
3779 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8));
3780 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16));
3781 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26));
3782 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56));
3783 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86));
3784 }while(0);
3785
3786 if (status<0)
3787 {
3788 //KdPrintEx((MSG_ERROR " - " __FUNCTION__ " status - %08x\n",status));
3789 }
3790 return status;
3791}
3792
3793/*============================================================================*/
3794
3795/**
3796* \brief QAM64 specific setup
3797* \param demod instance of demod.
3798* \return DRXStatus_t.
3799*/
3800static int SetQAM64 (struct drxk_state *state)
3801{
3802 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
3803 int status = 0;
3804 do
3805 {
3806 /* QAM Equalizer Setup */
3807 /* Equalizer */
3808 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336));
3809 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618));
3810 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988));
3811 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809));
3812 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809));
3813 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609));
3814
3815 /* Decision Feedback Equalizer */
3816 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN0__A, 4));
3817 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN1__A, 4));
3818 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN2__A, 4));
3819 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN3__A, 4));
3820 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN4__A, 3));
3821 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0));
3822
3823 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_HWM__A, 5));
3824 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_AWM__A, 4));
3825 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_LWM__A, 3));
3826
3827 /* QAM Slicer Settings */
3828 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64));
3829
3830
3831 /* QAM Loop Controller Coeficients */
3832
3833 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15));
3834 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40));
3835 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12));
3836 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24));
3837 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24));
3838 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12));
3839 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16));
3840 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16));
3841
3842 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5));
3843 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30));
3844 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100));
3845 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5));
3846 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30));
3847 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50));
3848 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16));
3849 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25));
3850 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48));
3851 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5));
3852 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10));
3853 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10));
3854
3855
3856 /* QAM State Machine (FSM) Thresholds */
3857
3858 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 100));
3859 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 60));
3860 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80));
3861 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 110));
3862 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 200));
3863 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 95));
3864
3865 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40));
3866 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4));
3867 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15));
3868
3869
3870 /* QAM FSM Tracking Parameters */
3871
3872 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12));
3873 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141));
3874 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7));
3875 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0));
3876 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15));
3877 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45));
3878 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80));
3879 }while(0);
3880
3881 if (status<0)
3882 {
3883 //KdPrintEx((MSG_ERROR " - " __FUNCTION__ " status - %08x\n",status));
3884 }
3885 return status;
3886}
3887
3888/*============================================================================*/
3889
3890/**
3891* \brief QAM128 specific setup
3892* \param demod: instance of demod.
3893* \return DRXStatus_t.
3894*/
3895static int SetQAM128(struct drxk_state *state)
3896{
3897 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
3898 int status = 0;
3899 do
3900 {
3901 /* QAM Equalizer Setup */
3902 /* Equalizer */
3903 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564));
3904 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598));
3905 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394));
3906 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409));
3907 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656));
3908 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238));
3909
3910 /* Decision Feedback Equalizer */
3911 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN0__A, 6));
3912 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN1__A, 6));
3913 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN2__A, 6));
3914 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN3__A, 6));
3915 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN4__A, 5));
3916 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0));
3917
3918 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_HWM__A, 6));
3919 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_AWM__A, 5));
3920 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_LWM__A, 3));
3921
3922
3923 /* QAM Slicer Settings */
3924
3925 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A,DRXK_QAM_SL_SIG_POWER_QAM128));
3926
3927
3928 /* QAM Loop Controller Coeficients */
3929
3930 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15));
3931 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40));
3932 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12));
3933 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24));
3934 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24));
3935 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12));
3936 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16));
3937 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16));
3938
3939 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5));
3940 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40));
3941 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120));
3942 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5));
3943 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40));
3944 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60));
3945 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16));
3946 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25));
3947 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64));
3948 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5));
3949 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10));
3950 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0));
3951
3952
3953 /* QAM State Machine (FSM) Thresholds */
3954
3955 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 50));
3956 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 60));
3957 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80));
3958 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 100));
3959 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 140));
3960 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 100));
3961
3962 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40));
3963 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5));
3964
3965 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12));
3966
3967 /* QAM FSM Tracking Parameters */
3968
3969 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8));
3970 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65));
3971 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5));
3972 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3));
3973 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1));
3974 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12));
3975 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23));
3976 }while(0);
3977
3978 if (status<0)
3979 {
3980 //KdPrintEx((MSG_ERROR " - " __FUNCTION__ " status - %08x\n",status));
3981 }
3982 return status;
3983}
3984
3985/*============================================================================*/
3986
3987/**
3988* \brief QAM256 specific setup
3989* \param demod: instance of demod.
3990* \return DRXStatus_t.
3991*/
3992static int SetQAM256(struct drxk_state *state)
3993{
3994 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
3995 int status = 0;
3996 do
3997 {
3998 /* QAM Equalizer Setup */
3999 /* Equalizer */
4000 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502));
4001 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084));
4002 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543));
4003 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931));
4004 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629));
4005 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385));
4006
4007 /* Decision Feedback Equalizer */
4008 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN0__A, 8));
4009 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN1__A, 8));
4010 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN2__A, 8));
4011 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN3__A, 8));
4012 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN4__A, 6));
4013 CHK_ERROR(Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0));
4014
4015 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_HWM__A, 5));
4016 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_AWM__A, 4));
4017 CHK_ERROR(Write16_0(state, QAM_SY_SYNC_LWM__A, 3));
4018
4019 /* QAM Slicer Settings */
4020
4021 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A,DRXK_QAM_SL_SIG_POWER_QAM256));
4022
4023
4024 /* QAM Loop Controller Coeficients */
4025
4026 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15));
4027 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40));
4028 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12));
4029 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24));
4030 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24));
4031 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12));
4032 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16));
4033 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16));
4034
4035 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5));
4036 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50));
4037 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250));
4038 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5));
4039 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50));
4040 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125));
4041 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16));
4042 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25));
4043 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48));
4044 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5));
4045 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10));
4046 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10));
4047
4048
4049 /* QAM State Machine (FSM) Thresholds */
4050
4051 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 50));
4052 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 60));
4053 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80));
4054 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 100));
4055 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 150));
4056 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 110));
4057
4058 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40));
4059 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4));
4060 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12));
4061
4062
4063 /* QAM FSM Tracking Parameters */
4064
4065 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8));
4066 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74));
4067 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18));
4068 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13));
4069 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7));
4070 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0));
4071 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8));
4072 }while(0);
4073
4074 if (status<0)
4075 {
4076 //KdPrintEx((MSG_ERROR " - " __FUNCTION__ " status - %08x\n",status));
4077 }
4078 return status;
4079}
4080
4081
4082/*============================================================================*/
4083/**
4084* \brief Reset QAM block.
4085* \param demod: instance of demod.
4086* \param channel: pointer to channel data.
4087* \return DRXStatus_t.
4088*/
4089static int QAMResetQAM(struct drxk_state *state)
4090{
4091 int status;
4092 u16 cmdResult;
4093
4094 //printk("%s\n", __FUNCTION__);
4095 do
4096 {
4097 /* Stop QAM comstate->m_exec */
4098 CHK_ERROR(Write16_0(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP));
4099
4100 CHK_ERROR(scu_command(state,SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET,0,NULL,1,&cmdResult));
4101 } while (0);
4102
4103 /* All done, all OK */
4104 return status;
4105}
4106
4107/*============================================================================*/
4108
4109/**
4110* \brief Set QAM symbolrate.
4111* \param demod: instance of demod.
4112* \param channel: pointer to channel data.
4113* \return DRXStatus_t.
4114*/
4115static int QAMSetSymbolrate(struct drxk_state *state)
4116{
4117 u32 adcFrequency = 0;
4118 u32 symbFreq = 0;
4119 u32 iqmRcRate = 0;
4120 u16 ratesel = 0;
4121 u32 lcSymbRate = 0;
4122 int status;
4123
4124 do
4125 {
4126 /* Select & calculate correct IQM rate */
4127 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
4128 ratesel = 0;
4129 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ " state->m_SymbolRate = %d\n",state->m_SymbolRate));
4130 //printk("SR %d\n", state->param.u.qam.symbol_rate);
4131 if (state->param.u.qam.symbol_rate <= 1188750)
4132 {
4133 ratesel = 3;
4134 }
4135 else if (state->param.u.qam.symbol_rate <= 2377500)
4136 {
4137 ratesel = 2;
4138 }
4139 else if (state->param.u.qam.symbol_rate <= 4755000)
4140 {
4141 ratesel = 1;
4142 }
4143 CHK_ERROR(Write16_0(state,IQM_FD_RATESEL__A, ratesel));
4144
4145 /*
4146 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
4147 */
4148 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
4149 if (symbFreq == 0)
4150 {
4151 /* Divide by zero */
4152 return -1;
4153 }
4154 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
4155 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
4156 (1 << 23);
4157 CHK_ERROR(Write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate,0));
4158 state->m_iqmRcRate = iqmRcRate;
4159 /*
4160 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
4161 */
4162 symbFreq = state->param.u.qam.symbol_rate;
4163 if (adcFrequency == 0)
4164 {
4165 /* Divide by zero */
4166 return -1;
4167 }
4168 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
4169 (Frac28a((symbFreq % adcFrequency), adcFrequency) >> 16);
4170 if (lcSymbRate > 511)
4171 {
4172 lcSymbRate = 511;
4173 }
4174 CHK_ERROR(Write16_0(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate));
4175 } while (0);
4176
4177 return status;
4178}
4179
4180/*============================================================================*/
4181
4182/**
4183* \brief Get QAM lock status.
4184* \param demod: instance of demod.
4185* \param channel: pointer to channel data.
4186* \return DRXStatus_t.
4187*/
4188
4189static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
4190{
4191 int status;
4192 u16 Result[2] = {0,0};
4193
4194 status = scu_command(state,SCU_RAM_COMMAND_STANDARD_QAM|SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2, Result);
4195 if (status<0)
4196 {
4197 printk("%s status = %08x\n",__FUNCTION__,status);
4198 }
4199 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED)
4200 {
4201 /* 0x0000 NOT LOCKED */
4202 *pLockStatus = NOT_LOCKED;
4203 }
4204 else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED)
4205 {
4206 /* 0x4000 DEMOD LOCKED */
4207 *pLockStatus = DEMOD_LOCK;
4208 }
4209 else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK)
4210 {
4211 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
4212 *pLockStatus = MPEG_LOCK;
4213 }
4214 else
4215 {
4216 /* 0xC000 NEVER LOCKED */
4217 /* (system will never be able to lock to the signal) */
4218 /* TODO: check this, intermediate & standard specific lock states are not
4219 taken into account here */
4220 *pLockStatus = NEVER_LOCK;
4221 }
4222 return status;
4223}
4224
4225#define QAM_MIRROR__M 0x03
4226#define QAM_MIRROR_NORMAL 0x00
4227#define QAM_MIRRORED 0x01
4228#define QAM_MIRROR_AUTO_ON 0x02
4229#define QAM_LOCKRANGE__M 0x10
4230#define QAM_LOCKRANGE_NORMAL 0x10
4231
4232static int SetQAM(struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerFreqOffset)
4233{
4234 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
4235 int status = 0;
4236 u8 parameterLen;
4237 u16 setEnvParameters[5];
4238 u16 setParamParameters[4]={0,0,0,0};
4239 u16 cmdResult;
4240
4241 //printk("%s\n", __FUNCTION__);
4242
4243 do {
4244 /*
4245 STEP 1: reset demodulator
4246 resets FEC DI and FEC RS
4247 resets QAM block
4248 resets SCU variables
4249 */
4250 CHK_ERROR(Write16_0(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP));
4251 CHK_ERROR(Write16_0(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP));
4252 CHK_ERROR(QAMResetQAM(state));
4253
4254 /*
4255 STEP 2: configure demodulator
4256 -set env
4257 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
4258 */
4259 CHK_ERROR(QAMSetSymbolrate(state));
4260
4261 /* Env parameters */
4262 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
4263 if (state->m_OperationMode == OM_QAM_ITU_C)
4264 {
4265 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
4266 }
4267 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
4268// check for LOCKRANGE Extented
4269 // setParamParameters[3] |= QAM_LOCKRANGE_NORMAL;
4270 parameterLen = 4;
4271
4272 /* Set params */
4273 switch(state->param.u.qam.modulation)
4274 {
4275 case QAM_256:
4276 state->m_Constellation = DRX_CONSTELLATION_QAM256;
4277 break;
4278 case QAM_AUTO:
4279 case QAM_64:
4280 state->m_Constellation = DRX_CONSTELLATION_QAM64;
4281 break;
4282 case QAM_16:
4283 state->m_Constellation = DRX_CONSTELLATION_QAM16;
4284 break;
4285 case QAM_32:
4286 state->m_Constellation = DRX_CONSTELLATION_QAM32;
4287 break;
4288 case QAM_128:
4289 state->m_Constellation = DRX_CONSTELLATION_QAM128;
4290 break;
4291 default:
4292 status = -EINVAL;
4293 break;
4294 }
4295 CHK_ERROR(status);
4296 setParamParameters[0] = state->m_Constellation; /* constellation */
4297 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
4298
4299 CHK_ERROR(scu_command(state,SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,4,setParamParameters,1,&cmdResult));
4300
4301
4302 /* STEP 3: enable the system in a mode where the ADC provides valid signal
4303 setup constellation independent registers */
4304// CHK_ERROR (SetFrequency (channel, tunerFreqOffset));
4305 CHK_ERROR (SetFrequencyShifter (state, IntermediateFreqkHz, tunerFreqOffset, true));
4306
4307 /* Setup BER measurement */
4308 CHK_ERROR(SetQAMMeasurement (state,
4309 state->m_Constellation,
4310 state->param.u.qam.symbol_rate));
4311
4312 /* Reset default values */
4313 CHK_ERROR(Write16_0(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE));
4314 CHK_ERROR(Write16_0(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE));
4315
4316 /* Reset default LC values */
4317 CHK_ERROR(Write16_0(state, QAM_LC_RATE_LIMIT__A, 3));
4318 CHK_ERROR(Write16_0(state, QAM_LC_LPF_FACTORP__A, 4));
4319 CHK_ERROR(Write16_0(state, QAM_LC_LPF_FACTORI__A, 4));
4320 CHK_ERROR(Write16_0(state, QAM_LC_MODE__A, 7));
4321
4322 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB0__A, 1));
4323 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB1__A, 1));
4324 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB2__A, 1));
4325 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB3__A, 1));
4326 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB4__A, 2));
4327 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB5__A, 2));
4328 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB6__A, 2));
4329 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB8__A, 2));
4330 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB9__A, 2));
4331 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB10__A, 2));
4332 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB12__A, 2));
4333 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB15__A, 3));
4334 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB16__A, 3));
4335 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB20__A, 4));
4336 CHK_ERROR(Write16_0(state, QAM_LC_QUAL_TAB25__A, 4));
4337
4338 /* Mirroring, QAM-block starting point not inverted */
4339 CHK_ERROR(Write16_0(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS));
4340
4341 /* Halt SCU to enable safe non-atomic accesses */
4342 CHK_ERROR(Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD));
4343
4344 /* STEP 4: constellation specific setup */
4345 switch (state->param.u.qam.modulation)
4346 {
4347 case QAM_16:
4348 CHK_ERROR(SetQAM16(state));
4349 break;
4350 case QAM_32:
4351 CHK_ERROR(SetQAM32(state));
4352 break;
4353 case QAM_AUTO:
4354 case QAM_64:
4355 CHK_ERROR(SetQAM64(state));
4356 break;
4357 case QAM_128:
4358 CHK_ERROR(SetQAM128(state));
4359 break;
4360 case QAM_256:
4361 //printk("SETQAM256\n");
4362 CHK_ERROR(SetQAM256(state));
4363 break;
4364 default:
4365 return -1;
4366 break;
4367 } /* switch */
4368 /* Activate SCU to enable SCU commands */
4369 CHK_ERROR(Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE));
4370
4371
4372 /* Re-configure MPEG output, requires knowledge of channel bitrate */
4373// extAttr->currentChannel.constellation = channel->constellation;
4374// extAttr->currentChannel.symbolrate = channel->symbolrate;
4375 CHK_ERROR(MPEGTSDtoSetup(state, state->m_OperationMode));
4376
4377 /* Start processes */
4378 CHK_ERROR(MPEGTSStart(state));
4379 CHK_ERROR(Write16_0(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE));
4380 CHK_ERROR(Write16_0(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE));
4381 CHK_ERROR(Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE));
4382
4383 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
4384 CHK_ERROR(scu_command(state,SCU_RAM_COMMAND_STANDARD_QAM |
4385 SCU_RAM_COMMAND_CMD_DEMOD_START,0,
4386 NULL,1,&cmdResult));
4387
4388 /* update global DRXK data container */
4389//? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17;
4390
4391 /* All done, all OK */
4392 } while(0);
4393
4394 if (status<0) {
4395 printk("%s %d\n", __FUNCTION__, status);
4396 }
4397 return status;
4398}
4399
4400static int SetQAMStandard(struct drxk_state *state, enum OperationMode oMode)
4401{
4402#ifdef DRXK_QAM_TAPS
4403#define DRXK_QAMA_TAPS_SELECT
4404#include "drxk_filters.h"
4405#undef DRXK_QAMA_TAPS_SELECT
4406#else
4407 int status;
4408#endif
4409
4410 //printk("%s\n", __FUNCTION__);
4411 do
4412 {
4413 /* added antenna switch */
4414 SwitchAntennaToQAM(state);
4415
4416 /* Ensure correct power-up mode */
4417 CHK_ERROR(PowerUpQAM(state));
4418 /* Reset QAM block */
4419 CHK_ERROR(QAMResetQAM(state));
4420
4421 /* Setup IQM */
4422
4423 CHK_ERROR(Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP));
4424 CHK_ERROR(Write16_0(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC));
4425
4426 /* Upload IQM Channel Filter settings by
4427 boot loader from ROM table */
4428 switch (oMode)
4429 {
4430 case OM_QAM_ITU_A:
4431 CHK_ERROR(BLChainCmd(state,
4432 DRXK_BL_ROM_OFFSET_TAPS_ITU_A,
4433 DRXK_BLCC_NR_ELEMENTS_TAPS,
4434 DRXK_BLC_TIMEOUT));
4435 break;
4436 case OM_QAM_ITU_C:
4437 CHK_ERROR(BLDirectCmd(state, IQM_CF_TAP_RE0__A,
4438 DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
4439 DRXK_BLDC_NR_ELEMENTS_TAPS,
4440 DRXK_BLC_TIMEOUT));
4441 CHK_ERROR(BLDirectCmd(state, IQM_CF_TAP_IM0__A,
4442 DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
4443 DRXK_BLDC_NR_ELEMENTS_TAPS,
4444 DRXK_BLC_TIMEOUT));
4445 break;
4446 default:
4447 status=-EINVAL;
4448 }
4449 CHK_ERROR (status);
4450
4451 CHK_ERROR(Write16_0(state, IQM_CF_OUT_ENA__A,
4452 (1 << IQM_CF_OUT_ENA_QAM__B)));
4453 CHK_ERROR(Write16_0(state, IQM_CF_SYMMETRIC__A, 0));
4454 CHK_ERROR(Write16_0(state, IQM_CF_MIDTAP__A,
4455 ((1 << IQM_CF_MIDTAP_RE__B) |
4456 (1 << IQM_CF_MIDTAP_IM__B))));
4457
4458 CHK_ERROR(Write16_0(state, IQM_RC_STRETCH__A, 21));
4459 CHK_ERROR(Write16_0(state, IQM_AF_CLP_LEN__A, 0));
4460 CHK_ERROR(Write16_0(state, IQM_AF_CLP_TH__A, 448));
4461 CHK_ERROR(Write16_0(state, IQM_AF_SNS_LEN__A, 0));
4462 CHK_ERROR(Write16_0(state, IQM_CF_POW_MEAS_LEN__A, 0));
4463
4464 CHK_ERROR(Write16_0(state, IQM_FS_ADJ_SEL__A, 1));
4465 CHK_ERROR(Write16_0(state, IQM_RC_ADJ_SEL__A, 1));
4466 CHK_ERROR(Write16_0(state, IQM_CF_ADJ_SEL__A, 1));
4467 CHK_ERROR(Write16_0(state, IQM_AF_UPD_SEL__A, 0));
4468
4469 /* IQM Impulse Noise Processing Unit */
4470 CHK_ERROR(Write16_0(state, IQM_CF_CLP_VAL__A, 500));
4471 CHK_ERROR(Write16_0(state, IQM_CF_DATATH__A, 1000));
4472 CHK_ERROR(Write16_0(state, IQM_CF_BYPASSDET__A, 1));
4473 CHK_ERROR(Write16_0(state, IQM_CF_DET_LCT__A, 0));
4474 CHK_ERROR(Write16_0(state, IQM_CF_WND_LEN__A, 1));
4475 CHK_ERROR(Write16_0(state, IQM_CF_PKDTH__A, 1));
4476 CHK_ERROR(Write16_0(state, IQM_AF_INC_BYPASS__A, 1));
4477
4478 /* turn on IQMAF. Must be done before setAgc**() */
4479 CHK_ERROR(SetIqmAf(state, true));
4480 CHK_ERROR(Write16_0(state, IQM_AF_START_LOCK__A, 0x01));
4481
4482 /* IQM will not be reset from here, sync ADC and update/init AGC */
4483 CHK_ERROR(ADCSynchronization (state));
4484
4485 /* Set the FSM step period */
4486 CHK_ERROR(Write16_0(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000));
4487
4488 /* Halt SCU to enable safe non-atomic accesses */
4489 CHK_ERROR(Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD));
4490
4491 /* No more resets of the IQM, current standard correctly set =>
4492 now AGCs can be configured. */
4493
4494 CHK_ERROR(InitAGC(state,true));
4495 CHK_ERROR(SetPreSaw(state, &(state->m_qamPreSawCfg)));
4496
4497 /* Configure AGC's */
4498 CHK_ERROR(SetAgcRf(state, &(state->m_qamRfAgcCfg), true));
4499 CHK_ERROR(SetAgcIf (state, &(state->m_qamIfAgcCfg), true));
4500
4501 /* Activate SCU to enable SCU commands */
4502 CHK_ERROR(Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE));
4503 } while (0);
4504 return status;
4505}
4506
4507static int WriteGPIO(struct drxk_state *state)
4508{
4509 int status;
4510 u16 value = 0;
4511
4512 do {
4513 /* stop lock indicator process */
4514 CHK_ERROR(Write16_0(state, SCU_RAM_GPIO__A,
4515 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE));
4516
4517 /* Write magic word to enable pdr reg write */
4518 CHK_ERROR(Write16_0(state, SIO_TOP_COMM_KEY__A,
4519 SIO_TOP_COMM_KEY_KEY));
4520
4521 if (state->m_hasSAWSW) {
4522 /* write to io pad configuration register - output mode */
4523 CHK_ERROR(Write16_0(state, SIO_PDR_SMA_TX_CFG__A,
4524 state->m_GPIOCfg));
4525
4526 /* use corresponding bit in io data output registar */
4527 CHK_ERROR(Read16_0(state, SIO_PDR_UIO_OUT_LO__A, &value));
4528 if (state->m_GPIO == 0) {
4529 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
4530 } else {
4531 value |= 0x8000; /* write one to 15th bit - 1st UIO */
4532 }
4533 /* write back to io data output register */
4534 CHK_ERROR(Write16_0(state, SIO_PDR_UIO_OUT_LO__A, value));
4535
4536 }
4537 /* Write magic word to disable pdr reg write */
4538 CHK_ERROR(Write16_0(state, SIO_TOP_COMM_KEY__A, 0x0000));
4539 } while (0);
4540 return status;
4541}
4542
4543static int SwitchAntennaToQAM(struct drxk_state *state)
4544{
4545 int status = -1;
4546
4547 if (state->m_AntennaSwitchDVBTDVBC != 0) {
4548 if (state->m_GPIO != state->m_AntennaDVBC) {
4549 state->m_GPIO = state->m_AntennaDVBC;
4550 status = WriteGPIO(state);
4551 }
4552 }
4553 return status;
4554}
4555
4556static int SwitchAntennaToDVBT(struct drxk_state *state)
4557{
4558 int status = -1;
4559 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
4560 if (state->m_AntennaSwitchDVBTDVBC != 0) {
4561 if (state->m_GPIO != state->m_AntennaDVBT) {
4562 state->m_GPIO = state->m_AntennaDVBT;
4563 status = WriteGPIO(state);
4564 }
4565 }
4566 return status;
4567}
4568
4569
4570static int PowerDownDevice(struct drxk_state *state)
4571{
4572 /* Power down to requested mode */
4573 /* Backup some register settings */
4574 /* Set pins with possible pull-ups connected to them in input mode */
4575 /* Analog power down */
4576 /* ADC power down */
4577 /* Power down device */
4578 int status;
4579 do {
4580 if (state->m_bPDownOpenBridge) {
4581 // Open I2C bridge before power down of DRXK
4582 CHK_ERROR(ConfigureI2CBridge(state, true));
4583 }
4584 // driver 0.9.0
4585 CHK_ERROR(DVBTEnableOFDMTokenRing(state, false));
4586
4587 CHK_ERROR(Write16_0(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK));
4588 CHK_ERROR(Write16_0(state, SIO_CC_UPDATE__A , SIO_CC_UPDATE_KEY));
4589 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
4590 CHK_ERROR(HI_CfgCommand(state));
4591 }
4592 while(0);
4593
4594 if (status<0) {
4595 //KdPrintEx((MSG_ERROR " - " __FUNCTION__ " status - %08x\n",status));
4596 return -1;
4597 }
4598 return 0;
4599}
4600
4601static int load_microcode(struct drxk_state *state, char *mc_name)
4602{
4603 const struct firmware *fw = NULL;
4604 int err=0;
4605
4606 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
4607 if (err < 0) {
4608 printk(KERN_ERR
4609 ": Could not load firmware file %s.\n", mc_name);
4610 printk(KERN_INFO
4611 ": Copy %s to your hotplug directory!\n", mc_name);
4612 return err;
4613 }
4614 err=DownloadMicrocode(state, fw->data, fw->size);
4615 release_firmware(fw);
4616 return err;
4617}
4618
4619static int init_drxk(struct drxk_state *state)
4620{
4621 int status;
4622 DRXPowerMode_t powerMode = DRXK_POWER_DOWN_OFDM;
4623 u16 driverVersion;
4624
4625 //printk("init_drxk\n");
4626 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
4627 do {
4628 CHK_ERROR(PowerUpDevice(state));
4629 CHK_ERROR (DRXX_Open(state));
4630 /* Soft reset of OFDM-, sys- and osc-clockdomain */
4631 CHK_ERROR(Write16_0(state, SIO_CC_SOFT_RST__A,
4632 SIO_CC_SOFT_RST_OFDM__M |
4633 SIO_CC_SOFT_RST_SYS__M |
4634 SIO_CC_SOFT_RST_OSC__M));
4635 CHK_ERROR(Write16_0(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY));
4636 /* TODO is this needed, if yes how much delay in worst case scenario */
4637 msleep(1);
4638 state->m_DRXK_A3_PATCH_CODE = true;
4639 CHK_ERROR(GetDeviceCapabilities(state));
4640
4641 /* Bridge delay, uses oscilator clock */
4642 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
4643 /* SDA brdige delay */
4644 state->m_HICfgBridgeDelay = (u16)((state->m_oscClockFreq/1000)* HI_I2C_BRIDGE_DELAY)/1000;
4645 /* Clipping */
4646 if (state->m_HICfgBridgeDelay > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)
4647 {
4648 state->m_HICfgBridgeDelay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
4649 }
4650 /* SCL bridge delay, same as SDA for now */
4651 state->m_HICfgBridgeDelay += state->m_HICfgBridgeDelay << SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
4652
4653 CHK_ERROR(InitHI(state));
4654 /* disable various processes */
4655#if NOA1ROM
4656 if (!(state->m_DRXK_A1_ROM_CODE) && !(state->m_DRXK_A2_ROM_CODE) )
4657#endif
4658 {
4659 CHK_ERROR(Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE));
4660 }
4661
4662 /* disable MPEG port */
4663 CHK_ERROR(MPEGTSDisable(state));
4664
4665 /* Stop AUD and SCU */
4666 CHK_ERROR(Write16_0(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP));
4667 CHK_ERROR(Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP));
4668
4669 /* enable token-ring bus through OFDM block for possible ucode upload */
4670 CHK_ERROR(Write16_0(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON));
4671
4672 /* include boot loader section */
4673 CHK_ERROR(Write16_0(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE));
4674 CHK_ERROR(BLChainCmd(state, 0, 6, 100));
4675
4676#if 0
4677 if (state->m_DRXK_A3_PATCH_CODE)
4678 CHK_ERROR(DownloadMicrocode(state,
4679 DRXK_A3_microcode,
4680 DRXK_A3_microcode_length));
4681#else
4682 load_microcode(state, "drxk_a3.mc");
4683#endif
4684#if NOA1ROM
4685 if (state->m_DRXK_A2_PATCH_CODE)
4686 CHK_ERROR(DownloadMicrocode(state,
4687 DRXK_A2_microcode,
4688 DRXK_A2_microcode_length));
4689#endif
4690 /* disable token-ring bus through OFDM block for possible ucode upload */
4691 CHK_ERROR(Write16_0(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF));
4692
4693 /* Run SCU for a little while to initialize microcode version numbers */
4694 CHK_ERROR(Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE));
4695 CHK_ERROR (DRXX_Open(state));
4696 // added for test
4697 msleep(30);
4698
4699 powerMode = DRXK_POWER_DOWN_OFDM;
4700 CHK_ERROR(CtrlPowerMode(state, &powerMode));
4701
4702 /* Stamp driver version number in SCU data RAM in BCD code
4703 Done to enable field application engineers to retreive drxdriver version
4704 via I2C from SCU RAM.
4705 Not using SCU command interface for SCU register access since no
4706 microcode may be present.
4707 */
4708 driverVersion = (((DRXK_VERSION_MAJOR/100) % 10) << 12) +
4709 (((DRXK_VERSION_MAJOR/10) % 10) << 8) +
4710 ((DRXK_VERSION_MAJOR%10) << 4) +
4711 (DRXK_VERSION_MINOR%10);
4712 CHK_ERROR(Write16_0(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion ));
4713 driverVersion = (((DRXK_VERSION_PATCH/1000) % 10) << 12) +
4714 (((DRXK_VERSION_PATCH/100) % 10) << 8) +
4715 (((DRXK_VERSION_PATCH/10) % 10) << 4) +
4716 (DRXK_VERSION_PATCH%10);
4717 CHK_ERROR(Write16_0(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion ));
4718
4719 printk("DRXK driver version:%d.%d.%d\n",
4720 DRXK_VERSION_MAJOR,DRXK_VERSION_MINOR,DRXK_VERSION_PATCH);
4721
4722 /* Dirty fix of default values for ROM/PATCH microcode
4723 Dirty because this fix makes it impossible to setup suitable values
4724 before calling DRX_Open. This solution requires changes to RF AGC speed
4725 to be done via the CTRL function after calling DRX_Open */
4726
4727 // m_dvbtRfAgcCfg.speed=3;
4728
4729 /* Reset driver debug flags to 0 */
4730 CHK_ERROR(Write16_0(state, SCU_RAM_DRIVER_DEBUG__A, 0));
4731 /* driver 0.9.0 */
4732 /* Setup FEC OC:
4733 NOTE: No more full FEC resets allowed afterwards!! */
4734 CHK_ERROR(Write16_0(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP));
4735 // MPEGTS functions are still the same
4736 CHK_ERROR(MPEGTSDtoInit(state));
4737 CHK_ERROR(MPEGTSStop(state));
4738 CHK_ERROR(MPEGTSConfigurePolarity(state));
4739 CHK_ERROR(MPEGTSConfigurePins(state, state->m_enableMPEGOutput));
4740 // added: configure GPIO
4741 CHK_ERROR(WriteGPIO(state));
4742
4743 state->m_DrxkState = DRXK_STOPPED;
4744
4745 if (state->m_bPowerDown) {
4746 CHK_ERROR(PowerDownDevice(state));
4747 state->m_DrxkState = DRXK_POWERED_DOWN;
4748 }
4749 else
4750 state->m_DrxkState = DRXK_STOPPED;
4751 } while(0);
4752 //printk("%s=%d\n", __FUNCTION__, status);
4753 }
4754 else
4755 {
4756 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ " - Init already done\n"));
4757 }
4758
4759 return 0;
4760}
4761
4762static void drxk_c_release(struct dvb_frontend* fe)
4763{
4764 struct drxk_state *state=fe->demodulator_priv;
4765 printk("%s\n", __FUNCTION__);
4766 kfree(state);
4767}
4768
4769static int drxk_c_init (struct dvb_frontend *fe)
4770{
4771 struct drxk_state *state=fe->demodulator_priv;
4772
4773 if (mutex_trylock(&state->ctlock)==0)
4774 return -EBUSY;
4775 SetOperationMode(state, OM_QAM_ITU_A);
4776 return 0;
4777}
4778
4779static int drxk_c_sleep(struct dvb_frontend* fe)
4780{
4781 struct drxk_state *state=fe->demodulator_priv;
4782
4783 ShutDown(state);
4784 mutex_unlock(&state->ctlock);
4785 return 0;
4786}
4787
4788static int drxk_gate_ctrl(struct dvb_frontend* fe, int enable)
4789{
4790 struct drxk_state *state = fe->demodulator_priv;
4791
4792 //printk("drxk_gate %d\n", enable);
4793 return ConfigureI2CBridge(state, enable ? true : false);
4794}
4795
4796static int drxk_set_parameters (struct dvb_frontend *fe,
4797 struct dvb_frontend_parameters *p)
4798{
4799 struct drxk_state *state = fe->demodulator_priv;
4800 u32 IF;
4801
4802 //printk("%s\n", __FUNCTION__);
4803
4804 if (fe->ops.i2c_gate_ctrl)
4805 fe->ops.i2c_gate_ctrl(fe, 1);
4806 if (fe->ops.tuner_ops.set_params)
4807 fe->ops.tuner_ops.set_params(fe, p);
4808 if (fe->ops.i2c_gate_ctrl)
4809 fe->ops.i2c_gate_ctrl(fe, 0);
4810 state->param=*p;
4811 fe->ops.tuner_ops.get_frequency(fe, &IF);
4812 Start(state, 0, IF);
4813
4814 //printk("%s IF=%d done\n", __FUNCTION__, IF);
4815 return 0;
4816}
4817
4818static int drxk_c_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
4819{
4820 //struct drxk_state *state = fe->demodulator_priv;
4821 //printk("%s\n", __FUNCTION__);
4822 return 0;
4823}
4824
4825static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
4826{
4827 struct drxk_state *state = fe->demodulator_priv;
4828 u32 stat;
4829
4830 *status=0;
4831 GetLockStatus(state, &stat, 0);
4832 if (stat==MPEG_LOCK)
4833 *status|=0x1f;
4834 if (stat==FEC_LOCK)
4835 *status|=0x0f;
4836 if (stat==DEMOD_LOCK)
4837 *status|=0x07;
4838 return 0;
4839}
4840
4841static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
4842{
4843 //struct drxk_state *state = fe->demodulator_priv;
4844 *ber=0;
4845 return 0;
4846}
4847
4848static int drxk_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
4849{
4850 struct drxk_state *state = fe->demodulator_priv;
4851 u32 val;
4852
4853 ReadIFAgc(state, &val);
4854 *strength = val & 0xffff;;
4855 return 0;
4856}
4857
4858static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
4859{
4860 struct drxk_state *state = fe->demodulator_priv;
4861 s32 snr2;
4862
4863 GetSignalToNoise(state, &snr2);
4864 *snr = snr2&0xffff;
4865 return 0;
4866}
4867
4868static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
4869{
4870 struct drxk_state *state = fe->demodulator_priv;
4871 u16 err;
4872
4873 DVBTQAMGetAccPktErr(state, &err);
4874 *ucblocks = (u32) err;
4875 return 0;
4876}
4877
4878static int drxk_c_get_tune_settings(struct dvb_frontend *fe,
4879 struct dvb_frontend_tune_settings *sets)
4880{
4881 sets->min_delay_ms=3000;
4882 sets->max_drift=0;
4883 sets->step_size=0;
4884 return 0;
4885}
4886
4887static void drxk_t_release(struct dvb_frontend* fe)
4888{
4889 //struct drxk_state *state=fe->demodulator_priv;
4890 //printk("%s\n", __FUNCTION__);
4891 //kfree(state);
4892}
4893
4894static int drxk_t_init (struct dvb_frontend *fe)
4895{
4896 struct drxk_state *state=fe->demodulator_priv;
4897 if (mutex_trylock(&state->ctlock)==0)
4898 return -EBUSY;
4899 //printk("%s\n", __FUNCTION__);
4900 SetOperationMode(state, OM_DVBT);
4901 //printk("%s done\n", __FUNCTION__);
4902 return 0;
4903}
4904
4905static int drxk_t_sleep(struct dvb_frontend* fe)
4906{
4907 struct drxk_state *state=fe->demodulator_priv;
4908 mutex_unlock(&state->ctlock);
4909 return 0;
4910}
4911
4912static int drxk_t_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
4913{
4914 //struct drxk_state *state = fe->demodulator_priv;
4915 //printk("%s\n", __FUNCTION__);
4916 return 0;
4917}
4918
4919static struct dvb_frontend_ops drxk_c_ops = {
4920 .info = {
4921 .name = "DRXK DVB-C",
4922 .type = FE_QAM,
4923 .frequency_stepsize = 62500,
4924 .frequency_min = 47000000,
4925 .frequency_max = 862000000,
4926 .symbol_rate_min = 870000,
4927 .symbol_rate_max = 11700000,
4928 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
4929 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO
4930 },
4931 .release = drxk_c_release,
4932 .init = drxk_c_init,
4933 .sleep = drxk_c_sleep,
4934 .i2c_gate_ctrl = drxk_gate_ctrl,
4935
4936 .set_frontend = drxk_set_parameters,
4937 .get_frontend = drxk_c_get_frontend,
4938 .get_tune_settings = drxk_c_get_tune_settings,
4939
4940 .read_status = drxk_read_status,
4941 .read_ber = drxk_read_ber,
4942 .read_signal_strength = drxk_read_signal_strength,
4943 .read_snr = drxk_read_snr,
4944 .read_ucblocks = drxk_read_ucblocks,
4945};
4946
4947static struct dvb_frontend_ops drxk_t_ops = {
4948 .info = {
4949 .name = "DRXK DVB-T",
4950 .type = FE_OFDM,
4951 .frequency_min = 47125000,
4952 .frequency_max = 865000000,
4953 .frequency_stepsize = 166667,
4954 .frequency_tolerance = 0,
4955 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
4956 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
4957 FE_CAN_FEC_AUTO |
4958 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
4959 FE_CAN_QAM_AUTO |
4960 FE_CAN_TRANSMISSION_MODE_AUTO |
4961 FE_CAN_GUARD_INTERVAL_AUTO |
4962 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
4963 FE_CAN_MUTE_TS
4964 },
4965 .release = drxk_t_release,
4966 .init = drxk_t_init,
4967 .sleep = drxk_t_sleep,
4968 .i2c_gate_ctrl = drxk_gate_ctrl,
4969
4970 .set_frontend = drxk_set_parameters,
4971 .get_frontend = drxk_t_get_frontend,
4972
4973 .read_status = drxk_read_status,
4974 .read_ber = drxk_read_ber,
4975 .read_signal_strength = drxk_read_signal_strength,
4976 .read_snr = drxk_read_snr,
4977 .read_ucblocks = drxk_read_ucblocks,
4978};
4979
4980struct dvb_frontend *drxk_attach(struct i2c_adapter *i2c, u8 adr,
4981 struct dvb_frontend **fe_t)
4982{
4983 struct drxk_state *state = NULL;
4984
4985 state=kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
4986 if (!state)
4987 return NULL;
4988
4989 state->i2c=i2c;
4990 state->demod_address=adr;
4991
4992 mutex_init(&state->mutex);
4993 mutex_init(&state->ctlock);
4994
4995 memcpy(&state->c_frontend.ops, &drxk_c_ops, sizeof(struct dvb_frontend_ops));
4996 memcpy(&state->t_frontend.ops, &drxk_t_ops, sizeof(struct dvb_frontend_ops));
4997 state->c_frontend.demodulator_priv=state;
4998 state->t_frontend.demodulator_priv=state;
4999
5000 init_state(state);
5001 if (init_drxk(state)<0)
5002 goto error;
5003 *fe_t = &state->t_frontend;
5004 return &state->c_frontend;
5005
5006error:
5007 printk("drxk: not found\n");
5008 kfree(state);
5009 return NULL;
5010}
5011
5012MODULE_DESCRIPTION("DRX-K driver");
5013MODULE_AUTHOR("Ralph Metzler");
5014MODULE_LICENSE("GPL");
5015
5016EXPORT_SYMBOL(drxk_attach);