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