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