blob: f7ae900811149ba81d1b0858ae9d8ae4b8a4cbff [file] [log] [blame]
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001/*
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);
Oliver Endrissebc7de22011-07-03 13:49:44 -030040static 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,
Ralph Metzler43dd07f2011-07-03 13:42:18 -030045 s32 tunerFreqOffset);
Oliver Endrissebc7de22011-07-03 13:49:44 -030046static int SetDVBTStandard(struct drxk_state *state,
47 enum OperationMode oMode);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030048static int DVBTStart(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030049static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
50 s32 tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030051static 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 ||
Oliver Endrissebc7de22011-07-03 13:49:44 -030064 state->m_OperationMode == OM_QAM_ITU_B ||
65 state->m_OperationMode == OM_QAM_ITU_C;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030066}
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
Ralph Metzler43dd07f2011-07-03 13:42:18 -030080#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
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300176static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300177{
178 u64 tmp64;
179
Oliver Endrissebc7de22011-07-03 13:49:44 -0300180 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300181 do_div(tmp64, c);
182
183 return (u32) tmp64;
184}
185
186inline u32 Frac28a(u32 a, u32 c)
187{
188 int i = 0;
189 u32 Q1 = 0;
190 u32 R0 = 0;
191
Oliver Endrissebc7de22011-07-03 13:49:44 -0300192 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
193 Q1 = a / c; /* integer part, only the 4 least significant bits
194 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300195
196 /* division using radix 16, 7 nibbles in the result */
197 for (i = 0; i < 7; i++) {
198 Q1 = (Q1 << 4) | (R0 / c);
199 R0 = (R0 % c) << 4;
200 }
201 /* rounding */
202 if ((R0 >> 3) >= c)
203 Q1++;
204
205 return Q1;
206}
207
208static u32 Log10Times100(u32 x)
209{
210 static const u8 scale = 15;
211 static const u8 indexWidth = 5;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300212 u8 i = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300213 u32 y = 0;
214 u32 d = 0;
215 u32 k = 0;
216 u32 r = 0;
217 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300218 log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
219 0 <= n < ((1<<INDEXWIDTH)+1)
220 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300221
222 static const u32 log2lut[] = {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300223 0, /* 0.000000 */
224 290941, /* 290941.300628 */
225 573196, /* 573196.476418 */
226 847269, /* 847269.179851 */
227 1113620, /* 1113620.489452 */
228 1372674, /* 1372673.576986 */
229 1624818, /* 1624817.752104 */
230 1870412, /* 1870411.981536 */
231 2109788, /* 2109787.962654 */
232 2343253, /* 2343252.817465 */
233 2571091, /* 2571091.461923 */
234 2793569, /* 2793568.696416 */
235 3010931, /* 3010931.055901 */
236 3223408, /* 3223408.452106 */
237 3431216, /* 3431215.635215 */
238 3634553, /* 3634553.498355 */
239 3833610, /* 3833610.244726 */
240 4028562, /* 4028562.434393 */
241 4219576, /* 4219575.925308 */
242 4406807, /* 4406806.721144 */
243 4590402, /* 4590401.736809 */
244 4770499, /* 4770499.491025 */
245 4947231, /* 4947230.734179 */
246 5120719, /* 5120719.018555 */
247 5291081, /* 5291081.217197 */
248 5458428, /* 5458427.996830 */
249 5622864, /* 5622864.249668 */
250 5784489, /* 5784489.488298 */
251 5943398, /* 5943398.207380 */
252 6099680, /* 6099680.215452 */
253 6253421, /* 6253420.939751 */
254 6404702, /* 6404701.706649 */
255 6553600, /* 6553600.000000 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300256 };
257
258
259 if (x == 0)
Oliver Endrissebc7de22011-07-03 13:49:44 -0300260 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300261
262 /* Scale x (normalize) */
263 /* computing y in log(x/y) = log(x) - log(y) */
264 if ((x & ((0xffffffff) << (scale + 1))) == 0) {
265 for (k = scale; k > 0; k--) {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300266 if (x & (((u32) 1) << scale))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300267 break;
268 x <<= 1;
269 }
270 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300271 for (k = scale; k < 31; k++) {
272 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300273 break;
274 x >>= 1;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300275 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300276 }
277 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300278 Now x has binary point between bit[scale] and bit[scale-1]
279 and 1.0 <= x < 2.0 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300280
281 /* correction for divison: log(x) = log(x/y)+log(y) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300282 y = k * ((((u32) 1) << scale) * 200);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300283
284 /* remove integer part */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300285 x &= ((((u32) 1) << scale) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300286 /* get index */
287 i = (u8) (x >> (scale - indexWidth));
288 /* compute delta (x - a) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300289 d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300290 /* compute log, multiplication (d* (..)) must be within range ! */
291 y += log2lut[i] +
Oliver Endrissebc7de22011-07-03 13:49:44 -0300292 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300293 /* Conver to log10() */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300294 y /= 108853; /* (log2(10) << scale) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300295 r = (y >> 1);
296 /* rounding */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300297 if (y & ((u32) 1))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300298 r++;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300299 return r;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300300}
301
302/****************************************************************************/
303/* I2C **********************************************************************/
304/****************************************************************************/
305
306static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val)
307{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300308 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
309 .buf = val, .len = 1}
310 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300311 return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
312}
313
314static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
315{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300316 struct i2c_msg msg = {
317 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300318
319 if (i2c_transfer(adap, &msg, 1) != 1) {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300320 printk(KERN_ERR "i2c_write error\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300321 return -1;
322 }
323 return 0;
324}
325
326static int i2c_read(struct i2c_adapter *adap,
327 u8 adr, u8 *msg, int len, u8 *answ, int alen)
328{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300329 struct i2c_msg msgs[2] = { {.addr = adr, .flags = 0,
330 .buf = msg, .len = len},
331 {.addr = adr, .flags = I2C_M_RD,
332 .buf = answ, .len = alen}
333 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300334 if (i2c_transfer(adap, msgs, 2) != 2) {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300335 printk(KERN_ERR "i2c_read error\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300336 return -1;
337 }
338 return 0;
339}
340
341static int Read16(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
342{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300343 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300344#ifdef I2C_LONG_ADR
345 flags |= 0xC0;
346#endif
347 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
348 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
349 mm1[1] = ((reg >> 16) & 0xFF);
350 mm1[2] = ((reg >> 24) & 0xFF) | flags;
351 mm1[3] = ((reg >> 7) & 0xFF);
352 len = 4;
353 } else {
354 mm1[0] = ((reg << 1) & 0xFF);
355 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
356 len = 2;
357 }
358 if (i2c_read(state->i2c, adr, mm1, len, mm2, 2) < 0)
359 return -1;
360 if (data)
361 *data = mm2[0] | (mm2[1] << 8);
362 return 0;
363}
364
365static int Read16_0(struct drxk_state *state, u32 reg, u16 *data)
366{
367 return Read16(state, reg, data, 0);
368}
369
370static int Read32(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
371{
372 u8 adr = state->demod_address, mm1[4], mm2[4], len;
373#ifdef I2C_LONG_ADR
374 flags |= 0xC0;
375#endif
376 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
377 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
378 mm1[1] = ((reg >> 16) & 0xFF);
379 mm1[2] = ((reg >> 24) & 0xFF) | flags;
380 mm1[3] = ((reg >> 7) & 0xFF);
381 len = 4;
382 } else {
383 mm1[0] = ((reg << 1) & 0xFF);
384 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
385 len = 2;
386 }
387 if (i2c_read(state->i2c, adr, mm1, len, mm2, 4) < 0)
388 return -1;
389 if (data)
390 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300391 (mm2[2] << 16) | (mm2[3] << 24);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300392 return 0;
393}
394
395static int Write16(struct drxk_state *state, u32 reg, u16 data, u8 flags)
396{
397 u8 adr = state->demod_address, mm[6], len;
398#ifdef I2C_LONG_ADR
399 flags |= 0xC0;
400#endif
401 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
402 mm[0] = (((reg << 1) & 0xFF) | 0x01);
403 mm[1] = ((reg >> 16) & 0xFF);
404 mm[2] = ((reg >> 24) & 0xFF) | flags;
405 mm[3] = ((reg >> 7) & 0xFF);
406 len = 4;
407 } else {
408 mm[0] = ((reg << 1) & 0xFF);
409 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
410 len = 2;
411 }
412 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300413 mm[len + 1] = (data >> 8) & 0xff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300414 if (i2c_write(state->i2c, adr, mm, len + 2) < 0)
415 return -1;
416 return 0;
417}
418
419static int Write16_0(struct drxk_state *state, u32 reg, u16 data)
420{
421 return Write16(state, reg, data, 0);
422}
423
424static int Write32(struct drxk_state *state, u32 reg, u32 data, u8 flags)
425{
426 u8 adr = state->demod_address, mm[8], len;
427#ifdef I2C_LONG_ADR
428 flags |= 0xC0;
429#endif
430 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
431 mm[0] = (((reg << 1) & 0xFF) | 0x01);
432 mm[1] = ((reg >> 16) & 0xFF);
433 mm[2] = ((reg >> 24) & 0xFF) | flags;
434 mm[3] = ((reg >> 7) & 0xFF);
435 len = 4;
436 } else {
437 mm[0] = ((reg << 1) & 0xFF);
438 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
439 len = 2;
440 }
441 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300442 mm[len + 1] = (data >> 8) & 0xff;
443 mm[len + 2] = (data >> 16) & 0xff;
444 mm[len + 3] = (data >> 24) & 0xff;
445 if (i2c_write(state->i2c, adr, mm, len + 4) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300446 return -1;
447 return 0;
448}
449
450static int WriteBlock(struct drxk_state *state, u32 Address,
451 const int BlockSize, const u8 pBlock[], u8 Flags)
452{
453 int status = 0, BlkSize = BlockSize;
454#ifdef I2C_LONG_ADR
455 Flags |= 0xC0;
456#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -0300457 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300458 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300459 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300460 u8 *AdrBuf = &state->Chunk[0];
461 u32 AdrLength = 0;
462
Oliver Endrissebc7de22011-07-03 13:49:44 -0300463 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
464 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
465 AdrBuf[1] = ((Address >> 16) & 0xFF);
466 AdrBuf[2] = ((Address >> 24) & 0xFF);
467 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300468 AdrBuf[2] |= Flags;
469 AdrLength = 4;
470 if (Chunk == state->m_ChunkSize)
471 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300472 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300473 AdrBuf[0] = ((Address << 1) & 0xFF);
474 AdrBuf[1] = (((Address >> 16) & 0x0F) |
475 ((Address >> 18) & 0xF0));
476 AdrLength = 2;
477 }
478 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
479 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300480 &state->Chunk[0], Chunk + AdrLength);
481 if (status < 0) {
482 printk(KERN_ERR "I2C Write error\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300483 break;
484 }
485 pBlock += Chunk;
486 Address += (Chunk >> 1);
487 BlkSize -= Chunk;
488 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300489 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300490}
491
492#ifndef DRXK_MAX_RETRIES_POWERUP
493#define DRXK_MAX_RETRIES_POWERUP 20
494#endif
495
496int PowerUpDevice(struct drxk_state *state)
497{
498 int status;
499 u8 data = 0;
500 u16 retryCount = 0;
501
502 status = i2c_read1(state->i2c, state->demod_address, &data);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300503 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300504 do {
505 data = 0;
506 if (i2c_write(state->i2c,
507 state->demod_address, &data, 1) < 0)
Oliver Endrissebc7de22011-07-03 13:49:44 -0300508 printk(KERN_ERR "powerup failed\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300509 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300510 retryCount++;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300511 } while (i2c_read1(state->i2c,
512 state->demod_address, &data) < 0 &&
513 (retryCount < DRXK_MAX_RETRIES_POWERUP));
514 if (retryCount >= DRXK_MAX_RETRIES_POWERUP)
515 return -1;
516 do {
517 /* Make sure all clk domains are active */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300518 status = Write16_0(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
519 if (status < 0)
520 break;
521 status = Write16_0(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
522 if (status < 0)
523 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300524 /* Enable pll lock tests */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300525 status = Write16_0(state, SIO_CC_PLL_LOCK__A, 1);
526 if (status < 0)
527 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300528 state->m_currentPowerMode = DRX_POWER_UP;
529 } while (0);
530 return status;
531}
532
533
534static int init_state(struct drxk_state *state)
535{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300536 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
537 u32 ulVSBIfAgcOutputLevel = 0;
538 u32 ulVSBIfAgcMinLevel = 0;
539 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
540 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300541
Oliver Endrissebc7de22011-07-03 13:49:44 -0300542 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
543 u32 ulVSBRfAgcOutputLevel = 0;
544 u32 ulVSBRfAgcMinLevel = 0;
545 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
546 u32 ulVSBRfAgcSpeed = 3;
547 u32 ulVSBRfAgcTop = 9500;
548 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300549
Oliver Endrissebc7de22011-07-03 13:49:44 -0300550 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
551 u32 ulATVIfAgcOutputLevel = 0;
552 u32 ulATVIfAgcMinLevel = 0;
553 u32 ulATVIfAgcMaxLevel = 0;
554 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300555
Oliver Endrissebc7de22011-07-03 13:49:44 -0300556 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
557 u32 ulATVRfAgcOutputLevel = 0;
558 u32 ulATVRfAgcMinLevel = 0;
559 u32 ulATVRfAgcMaxLevel = 0;
560 u32 ulATVRfAgcTop = 9500;
561 u32 ulATVRfAgcCutOffCurrent = 4000;
562 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300563
564 u32 ulQual83 = DEFAULT_MER_83;
565 u32 ulQual93 = DEFAULT_MER_93;
566
567 u32 ulDVBTStaticTSClock = 1;
568 u32 ulDVBCStaticTSClock = 1;
569
570 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
571 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
572
573 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
574 /* io_pad_cfg_mode output mode is drive always */
575 /* io_pad_cfg_drive is set to power 2 (23 mA) */
576 u32 ulGPIOCfg = 0x0113;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300577 u32 ulGPIO = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300578 u32 ulSerialMode = 1;
579 u32 ulInvertTSClock = 0;
580 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
581 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
582 u32 ulDVBTBitrate = 50000000;
583 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
584
585 u32 ulInsertRSByte = 0;
586
587 u32 ulRfMirror = 1;
588 u32 ulPowerDown = 0;
589
590 u32 ulAntennaDVBT = 1;
591 u32 ulAntennaDVBC = 0;
592 u32 ulAntennaSwitchDVBTDVBC = 0;
593
594 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300595 state->m_hasDVBT = false;
596 state->m_hasDVBC = false;
597 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300598 state->m_hasOOB = false;
599 state->m_hasAudio = false;
600
601 state->m_ChunkSize = 124;
602
603 state->m_oscClockFreq = 0;
604 state->m_smartAntInverted = false;
605 state->m_bPDownOpenBridge = false;
606
607 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300608 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300609 /* Timing div, 250ns/Psys */
610 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
611 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
612 HI_I2C_DELAY) / 1000;
613 /* Clipping */
614 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
615 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
616 state->m_HICfgWakeUpKey = (state->demod_address << 1);
617 /* port/bridge/power down ctrl */
618 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
619
620 state->m_bPowerDown = (ulPowerDown != 0);
621
622 state->m_DRXK_A1_PATCH_CODE = false;
623 state->m_DRXK_A1_ROM_CODE = false;
624 state->m_DRXK_A2_ROM_CODE = false;
625 state->m_DRXK_A3_ROM_CODE = false;
626 state->m_DRXK_A2_PATCH_CODE = false;
627 state->m_DRXK_A3_PATCH_CODE = false;
628
629 /* Init AGC and PGA parameters */
630 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300631 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
632 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
633 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
634 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
635 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300636 state->m_vsbPgaCfg = 140;
637
638 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300639 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
640 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
641 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
642 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
643 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
644 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
645 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
646 state->m_vsbPreSawCfg.reference = 0x07;
647 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300648
649 state->m_Quality83percent = DEFAULT_MER_83;
650 state->m_Quality93percent = DEFAULT_MER_93;
651 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
652 state->m_Quality83percent = ulQual83;
653 state->m_Quality93percent = ulQual93;
654 }
655
656 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300657 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
658 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
659 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
660 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
661 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300662
663 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300664 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
665 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
666 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
667 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
668 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
669 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
670 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
671 state->m_atvPreSawCfg.reference = 0x04;
672 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300673
674
675 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300676 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
677 state->m_dvbtRfAgcCfg.outputLevel = 0;
678 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
679 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
680 state->m_dvbtRfAgcCfg.top = 0x2100;
681 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
682 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300683
684
685 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300686 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
687 state->m_dvbtIfAgcCfg.outputLevel = 0;
688 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
689 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
690 state->m_dvbtIfAgcCfg.top = 13424;
691 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
692 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300693 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300694 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
695 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300696
Oliver Endrissebc7de22011-07-03 13:49:44 -0300697 state->m_dvbtPreSawCfg.reference = 4;
698 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300699
700 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300701 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
702 state->m_qamRfAgcCfg.outputLevel = 0;
703 state->m_qamRfAgcCfg.minOutputLevel = 6023;
704 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
705 state->m_qamRfAgcCfg.top = 0x2380;
706 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
707 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300708
709 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300710 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
711 state->m_qamIfAgcCfg.outputLevel = 0;
712 state->m_qamIfAgcCfg.minOutputLevel = 0;
713 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
714 state->m_qamIfAgcCfg.top = 0x0511;
715 state->m_qamIfAgcCfg.cutOffCurrent = 0;
716 state->m_qamIfAgcCfg.speed = 3;
717 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300718 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
719
Oliver Endrissebc7de22011-07-03 13:49:44 -0300720 state->m_qamPgaCfg = 140;
721 state->m_qamPreSawCfg.reference = 4;
722 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300723
724 state->m_OperationMode = OM_NONE;
725 state->m_DrxkState = DRXK_UNINITIALIZED;
726
727 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300728 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
729 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
730 state->m_enableParallel = true; /* If TRUE;
731 parallel out otherwise serial */
732 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
733 state->m_invertERR = false; /* If TRUE; invert ERR signal */
734 state->m_invertSTR = false; /* If TRUE; invert STR signals */
735 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
736 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300737 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300738 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300739 /* If TRUE; static MPEG clockrate will be used;
740 otherwise clockrate will adapt to the bitrate of the TS */
741
742 state->m_DVBTBitrate = ulDVBTBitrate;
743 state->m_DVBCBitrate = ulDVBCBitrate;
744
745 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
746 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
747
748 /* Maximum bitrate in b/s in case static clockrate is selected */
749 state->m_mpegTsStaticBitrate = 19392658;
750 state->m_disableTEIhandling = false;
751
752 if (ulInsertRSByte)
753 state->m_insertRSByte = true;
754
755 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
756 if (ulMpegLockTimeOut < 10000)
757 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
758 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
759 if (ulDemodLockTimeOut < 10000)
760 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
761
Oliver Endrissebc7de22011-07-03 13:49:44 -0300762 /* QAM defaults */
763 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300764 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300765 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
766 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300767
768 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
769 state->m_agcFastClipCtrlDelay = 0;
770
771 state->m_GPIOCfg = (ulGPIOCfg);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300772 state->m_GPIO = (ulGPIO == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300773
774 state->m_AntennaDVBT = (ulAntennaDVBT == 0 ? 0 : 1);
775 state->m_AntennaDVBC = (ulAntennaDVBC == 0 ? 0 : 1);
776 state->m_AntennaSwitchDVBTDVBC =
Oliver Endrissebc7de22011-07-03 13:49:44 -0300777 (ulAntennaSwitchDVBTDVBC == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300778
779 state->m_bPowerDown = false;
780 state->m_currentPowerMode = DRX_POWER_DOWN;
781
782 state->m_enableParallel = (ulSerialMode == 0);
783
784 state->m_rfmirror = (ulRfMirror == 0);
785 state->m_IfAgcPol = false;
786 return 0;
787}
788
789static int DRXX_Open(struct drxk_state *state)
790{
791 int status = 0;
792 u32 jtag = 0;
793 u16 bid = 0;
794 u16 key = 0;
795
796 do {
797 /* stop lock indicator process */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300798 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
799 if (status < 0)
800 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300801 /* Check device id */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300802 status = Read16(state, SIO_TOP_COMM_KEY__A, &key, 0);
803 if (status < 0)
804 break;
805 status = Write16_0(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
806 if (status < 0)
807 break;
808 status = Read32(state, SIO_TOP_JTAGID_LO__A, &jtag, 0);
809 if (status < 0)
810 break;
811 status = Read16(state, SIO_PDR_UIO_IN_HI__A, &bid, 0);
812 if (status < 0)
813 break;
814 status = Write16_0(state, SIO_TOP_COMM_KEY__A, key);
815 if (status < 0)
816 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300817 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300818 return status;
819}
820
821static int GetDeviceCapabilities(struct drxk_state *state)
822{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300823 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300824 u32 sioTopJtagidLo = 0;
825 int status;
826
827 do {
828 /* driver 0.9.0 */
829 /* stop lock indicator process */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300830 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
831 if (status < 0)
832 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300833
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300834 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0xFABA);
835 if (status < 0)
836 break;
837 status = Read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg, 0);
838 if (status < 0)
839 break;
840 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0x0000);
841 if (status < 0)
842 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300843
844 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
845 case 0:
846 /* ignore (bypass ?) */
847 break;
848 case 1:
849 /* 27 MHz */
850 state->m_oscClockFreq = 27000;
851 break;
852 case 2:
853 /* 20.25 MHz */
854 state->m_oscClockFreq = 20250;
855 break;
856 case 3:
857 /* 4 MHz */
858 state->m_oscClockFreq = 20250;
859 break;
860 default:
861 return -1;
862 }
863 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300864 Determine device capabilities
865 Based on pinning v14
866 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300867 status = Read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo, 0);
868 if (status < 0)
869 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300870 /* driver 0.9.0 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300871 switch ((sioTopJtagidLo >> 29) & 0xF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300872 case 0:
873 state->m_deviceSpin = DRXK_SPIN_A1;
874 break;
875 case 2:
876 state->m_deviceSpin = DRXK_SPIN_A2;
877 break;
878 case 3:
879 state->m_deviceSpin = DRXK_SPIN_A3;
880 break;
881 default:
882 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
883 status = -1;
884 break;
885 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300886 switch ((sioTopJtagidLo >> 12) & 0xFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300887 case 0x13:
888 /* typeId = DRX3913K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300889 state->m_hasLNA = false;
890 state->m_hasOOB = false;
891 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300892 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300893 state->m_hasDVBT = true;
894 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300895 state->m_hasSAWSW = true;
896 state->m_hasGPIO2 = false;
897 state->m_hasGPIO1 = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300898 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300899 break;
900 case 0x15:
901 /* typeId = DRX3915K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300902 state->m_hasLNA = false;
903 state->m_hasOOB = false;
904 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300905 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300906 state->m_hasDVBT = true;
907 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300908 state->m_hasSAWSW = true;
909 state->m_hasGPIO2 = true;
910 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300911 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300912 break;
913 case 0x16:
914 /* typeId = DRX3916K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300915 state->m_hasLNA = false;
916 state->m_hasOOB = false;
917 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300918 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300919 state->m_hasDVBT = true;
920 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300921 state->m_hasSAWSW = true;
922 state->m_hasGPIO2 = true;
923 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300924 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300925 break;
926 case 0x18:
927 /* typeId = DRX3918K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300928 state->m_hasLNA = false;
929 state->m_hasOOB = false;
930 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300931 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300932 state->m_hasDVBT = true;
933 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300934 state->m_hasSAWSW = true;
935 state->m_hasGPIO2 = true;
936 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300937 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300938 break;
939 case 0x21:
940 /* typeId = DRX3921K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300941 state->m_hasLNA = false;
942 state->m_hasOOB = false;
943 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300944 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300945 state->m_hasDVBT = true;
946 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300947 state->m_hasSAWSW = true;
948 state->m_hasGPIO2 = true;
949 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300950 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300951 break;
952 case 0x23:
953 /* typeId = DRX3923K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300954 state->m_hasLNA = false;
955 state->m_hasOOB = false;
956 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300957 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300958 state->m_hasDVBT = true;
959 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300960 state->m_hasSAWSW = true;
961 state->m_hasGPIO2 = true;
962 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300963 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300964 break;
965 case 0x25:
966 /* typeId = DRX3925K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300967 state->m_hasLNA = false;
968 state->m_hasOOB = false;
969 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300970 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300971 state->m_hasDVBT = true;
972 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300973 state->m_hasSAWSW = true;
974 state->m_hasGPIO2 = true;
975 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300976 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300977 break;
978 case 0x26:
979 /* typeId = DRX3926K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300980 state->m_hasLNA = false;
981 state->m_hasOOB = false;
982 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300983 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300984 state->m_hasDVBT = true;
985 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300986 state->m_hasSAWSW = true;
987 state->m_hasGPIO2 = true;
988 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300989 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300990 break;
991 default:
Oliver Endrissebc7de22011-07-03 13:49:44 -0300992 printk(KERN_ERR "DeviceID not supported = %02x\n",
993 ((sioTopJtagidLo >> 12) & 0xFF));
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300994 status = -1;
995 break;
996 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300997 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300998 return status;
999}
1000
1001static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1002{
1003 int status;
1004 bool powerdown_cmd;
1005
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001006 /* Write command */
1007 status = Write16_0(state, SIO_HI_RA_RAM_CMD__A, cmd);
1008 if (status < 0)
1009 return status;
1010 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1011 msleep(1);
1012
1013 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001014 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1015 ((state->m_HICfgCtrl) &
1016 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1017 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001018 if (powerdown_cmd == false) {
1019 /* Wait until command rdy */
1020 u32 retryCount = 0;
1021 u16 waitCmd;
1022
1023 do {
1024 msleep(1);
1025 retryCount += 1;
1026 status = Read16(state, SIO_HI_RA_RAM_CMD__A,
1027 &waitCmd, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001028 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1029 && (waitCmd != 0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001030
1031 if (status == 0)
1032 status = Read16(state, SIO_HI_RA_RAM_RES__A,
1033 pResult, 0);
1034 }
1035 return status;
1036}
1037
1038static int HI_CfgCommand(struct drxk_state *state)
1039{
1040 int status;
1041
1042 mutex_lock(&state->mutex);
1043 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001044 status = Write16_0(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1045 if (status < 0)
1046 break;
1047 status = Write16_0(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1048 if (status < 0)
1049 break;
1050 status = Write16_0(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1051 if (status < 0)
1052 break;
1053 status = Write16_0(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1054 if (status < 0)
1055 break;
1056 status = Write16_0(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1057 if (status < 0)
1058 break;
1059 status = Write16_0(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1060 if (status < 0)
1061 break;
1062 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1063 if (status < 0)
1064 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001065
1066 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001067 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001068 mutex_unlock(&state->mutex);
1069 return status;
1070}
1071
1072static int InitHI(struct drxk_state *state)
1073{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001074 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001075 state->m_HICfgTimeout = 0x96FF;
1076 /* port/bridge/power down ctrl */
1077 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001078 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001079}
1080
1081static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1082{
1083 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001084 u16 sioPdrMclkCfg = 0;
1085 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001086
1087 do {
1088 /* stop lock indicator process */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001089 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1090 if (status < 0)
1091 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001092
1093 /* MPEG TS pad configuration */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001094 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1095 if (status < 0)
1096 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001097
1098 if (mpegEnable == false) {
1099 /* Set MPEG TS pads to inputmode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001100 status = Write16_0(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1101 if (status < 0)
1102 break;
1103 status = Write16_0(state, SIO_PDR_MERR_CFG__A, 0x0000);
1104 if (status < 0)
1105 break;
1106 status = Write16_0(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1107 if (status < 0)
1108 break;
1109 status = Write16_0(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1110 if (status < 0)
1111 break;
1112 status = Write16_0(state, SIO_PDR_MD0_CFG__A, 0x0000);
1113 if (status < 0)
1114 break;
1115 status = Write16_0(state, SIO_PDR_MD1_CFG__A, 0x0000);
1116 if (status < 0)
1117 break;
1118 status = Write16_0(state, SIO_PDR_MD2_CFG__A, 0x0000);
1119 if (status < 0)
1120 break;
1121 status = Write16_0(state, SIO_PDR_MD3_CFG__A, 0x0000);
1122 if (status < 0)
1123 break;
1124 status = Write16_0(state, SIO_PDR_MD4_CFG__A, 0x0000);
1125 if (status < 0)
1126 break;
1127 status = Write16_0(state, SIO_PDR_MD5_CFG__A, 0x0000);
1128 if (status < 0)
1129 break;
1130 status = Write16_0(state, SIO_PDR_MD6_CFG__A, 0x0000);
1131 if (status < 0)
1132 break;
1133 status = Write16_0(state, SIO_PDR_MD7_CFG__A, 0x0000);
1134 if (status < 0)
1135 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001136 } else {
1137 /* Enable MPEG output */
1138 sioPdrMdxCfg =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001139 ((state->m_TSDataStrength <<
1140 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001141 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03001142 SIO_PDR_MCLK_CFG_DRIVE__B) |
1143 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001144
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001145 status = Write16_0(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1146 if (status < 0)
1147 break;
1148 status = Write16_0(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
1149 if (status < 0)
1150 break;
1151 status = Write16_0(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
1152 if (status < 0)
1153 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001154 if (state->m_enableParallel == true) {
1155 /* paralel -> enable MD1 to MD7 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001156 status = Write16_0(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
1157 if (status < 0)
1158 break;
1159 status = Write16_0(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
1160 if (status < 0)
1161 break;
1162 status = Write16_0(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
1163 if (status < 0)
1164 break;
1165 status = Write16_0(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
1166 if (status < 0)
1167 break;
1168 status = Write16_0(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
1169 if (status < 0)
1170 break;
1171 status = Write16_0(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1172 if (status < 0)
1173 break;
1174 status = Write16_0(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1175 if (status < 0)
1176 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001177 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001178 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1179 SIO_PDR_MD0_CFG_DRIVE__B)
1180 | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001181 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001182 status = Write16_0(state, SIO_PDR_MD1_CFG__A, 0x0000);
1183 if (status < 0)
1184 break;
1185 status = Write16_0(state, SIO_PDR_MD2_CFG__A, 0x0000);
1186 if (status < 0)
1187 break;
1188 status = Write16_0(state, SIO_PDR_MD3_CFG__A, 0x0000);
1189 if (status < 0)
1190 break;
1191 status = Write16_0(state, SIO_PDR_MD4_CFG__A, 0x0000);
1192 if (status < 0)
1193 break;
1194 status = Write16_0(state, SIO_PDR_MD5_CFG__A, 0x0000);
1195 if (status < 0)
1196 break;
1197 status = Write16_0(state, SIO_PDR_MD6_CFG__A, 0x0000);
1198 if (status < 0)
1199 break;
1200 status = Write16_0(state, SIO_PDR_MD7_CFG__A, 0x0000);
1201 if (status < 0)
1202 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001203 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001204 status = Write16_0(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
1205 if (status < 0)
1206 break;
1207 status = Write16_0(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
1208 if (status < 0)
1209 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001210 }
1211 /* Enable MB output over MPEG pads and ctl input */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001212 status = Write16_0(state, SIO_PDR_MON_CFG__A, 0x0000);
1213 if (status < 0)
1214 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001215 /* Write nomagic word to enable pdr reg write */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001216 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0x0000);
1217 if (status < 0)
1218 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001219 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001220 return status;
1221}
1222
1223static int MPEGTSDisable(struct drxk_state *state)
1224{
1225 return MPEGTSConfigurePins(state, false);
1226}
1227
1228static int BLChainCmd(struct drxk_state *state,
1229 u16 romOffset, u16 nrOfElements, u32 timeOut)
1230{
1231 u16 blStatus = 0;
1232 int status;
1233 unsigned long end;
1234
1235 mutex_lock(&state->mutex);
1236 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001237 status = Write16_0(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1238 if (status < 0)
1239 break;
1240 status = Write16_0(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1241 if (status < 0)
1242 break;
1243 status = Write16_0(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1244 if (status < 0)
1245 break;
1246 status = Write16_0(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1247 if (status < 0)
1248 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001249 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001250
1251 do {
1252 msleep(1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001253 status = Read16(state, SIO_BL_STATUS__A, &blStatus, 0);
1254 if (status < 0)
1255 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001256 } while ((blStatus == 0x1) &&
1257 ((time_is_after_jiffies(end))));
1258 if (blStatus == 0x1) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001259 printk(KERN_ERR "SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001260 mutex_unlock(&state->mutex);
1261 return -1;
1262 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001263 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001264 mutex_unlock(&state->mutex);
1265 return status;
1266}
1267
1268
1269static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001270 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001271{
1272 const u8 *pSrc = pMCImage;
1273 u16 Flags;
1274 u16 Drain;
1275 u32 Address;
1276 u16 nBlocks;
1277 u16 BlockSize;
1278 u16 BlockCRC;
1279 u32 offset = 0;
1280 u32 i;
1281 int status;
1282
1283 /* down the drain (we don care about MAGIC_WORD) */
1284 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001285 pSrc += sizeof(u16);
1286 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001287 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001288 pSrc += sizeof(u16);
1289 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001290
1291 for (i = 0; i < nBlocks; i += 1) {
1292 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001293 (pSrc[2] << 8) | pSrc[3];
1294 pSrc += sizeof(u32);
1295 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001296
1297 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001298 pSrc += sizeof(u16);
1299 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001300
1301 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001302 pSrc += sizeof(u16);
1303 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001304
1305 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001306 pSrc += sizeof(u16);
1307 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001308 status = WriteBlock(state, Address, BlockSize, pSrc, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001309 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001310 break;
1311 pSrc += BlockSize;
1312 offset += BlockSize;
1313 }
1314 return status;
1315}
1316
1317static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1318{
1319 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001320 u16 data = 0;
1321 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001322 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1323 unsigned long end;
1324
1325 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001326 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001327 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1328 }
1329
Oliver Endrissebc7de22011-07-03 13:49:44 -03001330 status = (Read16_0(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001331
1332 if (data == desiredStatus) {
1333 /* tokenring already has correct status */
1334 return status;
1335 }
1336 /* Disable/enable dvbt tokenring bridge */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001337 status =
1338 Write16_0(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001339
Oliver Endrissebc7de22011-07-03 13:49:44 -03001340 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001341 do {
1342 status = Read16_0(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1343 if (status < 0)
1344 break;
1345 } while ((data != desiredStatus) && ((time_is_after_jiffies(end))));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001346 if (data != desiredStatus) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001347 printk(KERN_ERR "SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001348 return -1;
1349 }
1350 return status;
1351}
1352
1353static int MPEGTSStop(struct drxk_state *state)
1354{
1355 int status = 0;
1356 u16 fecOcSncMode = 0;
1357 u16 fecOcIprMode = 0;
1358
1359 do {
1360 /* Gracefull shutdown (byte boundaries) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001361 status = Read16_0(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1362 if (status < 0)
1363 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001364 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001365 status = Write16_0(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1366 if (status < 0)
1367 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001368
1369 /* Suppress MCLK during absence of data */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001370 status = Read16_0(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1371 if (status < 0)
1372 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001373 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001374 status = Write16_0(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1375 if (status < 0)
1376 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001377 } while (0);
1378 return status;
1379}
1380
1381static int scu_command(struct drxk_state *state,
1382 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001383 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001384{
1385#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1386#error DRXK register mapping no longer compatible with this routine!
1387#endif
1388 u16 curCmd = 0;
1389 int status;
1390 unsigned long end;
1391
1392 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1393 ((resultLen > 0) && (result == NULL)))
1394 return -1;
1395
1396 mutex_lock(&state->mutex);
1397 do {
1398 /* assume that the command register is ready
1399 since it is checked afterwards */
1400 u8 buffer[34];
1401 int cnt = 0, ii;
1402
Oliver Endrissebc7de22011-07-03 13:49:44 -03001403 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001404 buffer[cnt++] = (parameter[ii] & 0xFF);
1405 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1406 }
1407 buffer[cnt++] = (cmd & 0xFF);
1408 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1409
1410 WriteBlock(state, SCU_RAM_PARAM_0__A -
Oliver Endrissebc7de22011-07-03 13:49:44 -03001411 (parameterLen - 1), cnt, buffer, 0x00);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001412 /* Wait until SCU has processed command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001413 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001414 do {
1415 msleep(1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001416 status = Read16_0(state, SCU_RAM_COMMAND__A, &curCmd);
1417 if (status < 0)
1418 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001419 } while (!(curCmd == DRX_SCU_READY)
1420 && (time_is_after_jiffies(end)));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001421 if (curCmd != DRX_SCU_READY) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001422 printk(KERN_ERR "SCU not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001423 mutex_unlock(&state->mutex);
1424 return -1;
1425 }
1426 /* read results */
1427 if ((resultLen > 0) && (result != NULL)) {
1428 s16 err;
1429 int ii;
1430
Oliver Endrissebc7de22011-07-03 13:49:44 -03001431 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001432 status = Read16_0(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
1433 if (status < 0)
1434 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001435 }
1436
1437 /* Check if an error was reported by SCU */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001438 err = (s16) result[0];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001439
1440 /* check a few fixed error codes */
1441 if (err == SCU_RESULT_UNKSTD) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001442 printk(KERN_ERR "SCU_RESULT_UNKSTD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001443 mutex_unlock(&state->mutex);
1444 return -1;
1445 } else if (err == SCU_RESULT_UNKCMD) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001446 printk(KERN_ERR "SCU_RESULT_UNKCMD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001447 mutex_unlock(&state->mutex);
1448 return -1;
1449 }
1450 /* here it is assumed that negative means error,
1451 and positive no error */
1452 else if (err < 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001453 printk(KERN_ERR "%s ERROR\n", __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001454 mutex_unlock(&state->mutex);
1455 return -1;
1456 }
1457 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001458 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001459 mutex_unlock(&state->mutex);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001460 if (status < 0)
1461 printk(KERN_ERR "%s: status = %d\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001462
1463 return status;
1464}
1465
1466static int SetIqmAf(struct drxk_state *state, bool active)
1467{
1468 u16 data = 0;
1469 int status;
1470
Oliver Endrissebc7de22011-07-03 13:49:44 -03001471 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001472 /* Configure IQM */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001473 status = Read16_0(state, IQM_AF_STDBY__A, &data);
1474 if (status < 0)
1475 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001476 if (!active) {
1477 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1478 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1479 | IQM_AF_STDBY_STDBY_PD_STANDBY
1480 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
Oliver Endrissebc7de22011-07-03 13:49:44 -03001481 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1482 } else { /* active */
1483
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001484 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1485 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1486 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1487 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1488 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
Oliver Endrissebc7de22011-07-03 13:49:44 -03001489 );
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001490 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001491 status = Write16_0(state, IQM_AF_STDBY__A, data);
1492 if (status < 0)
1493 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001494 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001495 return status;
1496}
1497
Oliver Endrissebc7de22011-07-03 13:49:44 -03001498static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001499{
1500 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001501 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001502
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001503 /* Check arguments */
1504 if (mode == NULL)
1505 return -1;
1506
1507 switch (*mode) {
1508 case DRX_POWER_UP:
1509 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1510 break;
1511 case DRXK_POWER_DOWN_OFDM:
1512 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1513 break;
1514 case DRXK_POWER_DOWN_CORE:
1515 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1516 break;
1517 case DRXK_POWER_DOWN_PLL:
1518 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1519 break;
1520 case DRX_POWER_DOWN:
1521 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1522 break;
1523 default:
1524 /* Unknow sleep mode */
1525 return -1;
1526 break;
1527 }
1528
1529 /* If already in requested power mode, do nothing */
1530 if (state->m_currentPowerMode == *mode)
1531 return 0;
1532
1533 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001534 if (state->m_currentPowerMode != DRX_POWER_UP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001535 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001536 status = PowerUpDevice(state);
1537 if (status < 0)
1538 break;
1539 status = DVBTEnableOFDMTokenRing(state, true);
1540 if (status < 0)
1541 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001542 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001543 }
1544
1545 if (*mode == DRX_POWER_UP) {
1546 /* Restore analog & pin configuartion */
1547 } else {
1548 /* Power down to requested mode */
1549 /* Backup some register settings */
1550 /* Set pins with possible pull-ups connected
1551 to them in input mode */
1552 /* Analog power down */
1553 /* ADC power down */
1554 /* Power down device */
1555 /* stop all comm_exec */
1556 /* Stop and power down previous standard */
1557 do {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001558 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001559 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001560 status = MPEGTSStop(state);
1561 if (status < 0)
1562 break;
1563 status = PowerDownDVBT(state, false);
1564 if (status < 0)
1565 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001566 break;
1567 case OM_QAM_ITU_A:
1568 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001569 status = MPEGTSStop(state);
1570 if (status < 0)
1571 break;
1572 status = PowerDownQAM(state);
1573 if (status < 0)
1574 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001575 break;
1576 default:
1577 break;
1578 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001579 status = DVBTEnableOFDMTokenRing(state, false);
1580 if (status < 0)
1581 break;
1582 status = Write16_0(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1583 if (status < 0)
1584 break;
1585 status = Write16_0(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1586 if (status < 0)
1587 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001588
Oliver Endrissebc7de22011-07-03 13:49:44 -03001589 if (*mode != DRXK_POWER_DOWN_OFDM) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001590 state->m_HICfgCtrl |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03001591 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001592 status = HI_CfgCommand(state);
1593 if (status < 0)
1594 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001595 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001596 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001597 }
1598 state->m_currentPowerMode = *mode;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001599 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001600}
1601
1602static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1603{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001604 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001605 u16 cmdResult = 0;
1606 u16 data = 0;
1607 int status;
1608
1609 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001610 status = Read16_0(state, SCU_COMM_EXEC__A, &data);
1611 if (status < 0)
1612 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001613 if (data == SCU_COMM_EXEC_ACTIVE) {
1614 /* Send OFDM stop command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001615 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
1616 if (status < 0)
1617 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001618 /* Send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001619 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1620 if (status < 0)
1621 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001622 }
1623
1624 /* Reset datapath for OFDM, processors first */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001625 status = Write16_0(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1626 if (status < 0)
1627 break;
1628 status = Write16_0(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1629 if (status < 0)
1630 break;
1631 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1632 if (status < 0)
1633 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001634
1635 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001636 status = SetIqmAf(state, false);
1637 if (status < 0)
1638 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001639
1640 /* powerdown to OFDM mode */
1641 if (setPowerMode) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001642 status = CtrlPowerMode(state, &powerMode);
1643 if (status < 0)
1644 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001645 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001646 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001647 return status;
1648}
1649
Oliver Endrissebc7de22011-07-03 13:49:44 -03001650static int SetOperationMode(struct drxk_state *state,
1651 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001652{
1653 int status = 0;
1654
1655 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001656 Stop and power down previous standard
1657 TODO investigate total power down instead of partial
1658 power down depending on "previous" standard.
1659 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001660 do {
1661 /* disable HW lock indicator */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001662 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1663 if (status < 0)
1664 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001665
1666 if (state->m_OperationMode != oMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001667 switch (state->m_OperationMode) {
1668 /* OM_NONE was added for start up */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001669 case OM_NONE:
1670 break;
1671 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001672 status = MPEGTSStop(state);
1673 if (status < 0)
1674 break;
1675 status = PowerDownDVBT(state, true);
1676 if (status < 0)
1677 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001678 state->m_OperationMode = OM_NONE;
1679 break;
1680 case OM_QAM_ITU_B:
1681 status = -1;
1682 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001683 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001684 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001685 status = MPEGTSStop(state);
1686 if (status < 0)
1687 break;
1688 status = PowerDownQAM(state);
1689 if (status < 0)
1690 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001691 state->m_OperationMode = OM_NONE;
1692 break;
1693 default:
1694 status = -1;
1695 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001696 status = status;
1697 if (status < 0)
1698 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001699
1700 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001701 Power up new standard
1702 */
1703 switch (oMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001704 case OM_DVBT:
1705 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001706 status = SetDVBTStandard(state, oMode);
1707 if (status < 0)
1708 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001709 break;
1710 case OM_QAM_ITU_B:
1711 status = -1;
1712 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001713 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001714 case OM_QAM_ITU_C:
1715 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001716 status = SetQAMStandard(state, oMode);
1717 if (status < 0)
1718 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001719 break;
1720 default:
1721 status = -1;
1722 }
1723 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001724 status = status;
1725 if (status < 0)
1726 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001727 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001728 return 0;
1729}
1730
1731static int Start(struct drxk_state *state, s32 offsetFreq,
1732 s32 IntermediateFrequency)
1733{
1734 int status;
1735
1736 do {
1737 u16 IFreqkHz;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001738 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001739
1740 if (state->m_DrxkState != DRXK_STOPPED &&
1741 state->m_DrxkState != DRXK_DTV_STARTED) {
1742 status = -1;
1743 break;
1744 }
1745 state->m_bMirrorFreqSpect =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001746 (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001747
1748 if (IntermediateFrequency < 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001749 state->m_bMirrorFreqSpect =
1750 !state->m_bMirrorFreqSpect;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001751 IntermediateFrequency = -IntermediateFrequency;
1752 }
1753
Oliver Endrissebc7de22011-07-03 13:49:44 -03001754 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001755 case OM_QAM_ITU_A:
1756 case OM_QAM_ITU_C:
1757 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001758 status = SetQAM(state, IFreqkHz, OffsetkHz);
1759 if (status < 0)
1760 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001761 state->m_DrxkState = DRXK_DTV_STARTED;
1762 break;
1763 case OM_DVBT:
1764 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001765 status = MPEGTSStop(state);
1766 if (status < 0)
1767 break;
1768 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1769 if (status < 0)
1770 break;
1771 status = DVBTStart(state);
1772 if (status < 0)
1773 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001774 state->m_DrxkState = DRXK_DTV_STARTED;
1775 break;
1776 default:
1777 break;
1778 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001779 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001780 return status;
1781}
1782
1783static int ShutDown(struct drxk_state *state)
1784{
1785 MPEGTSStop(state);
1786 return 0;
1787}
1788
Oliver Endrissebc7de22011-07-03 13:49:44 -03001789static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1790 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001791{
1792 int status;
1793
1794 if (pLockStatus == NULL)
1795 return -1;
1796
1797 *pLockStatus = NOT_LOCKED;
1798
1799 /* define the SCU command code */
1800 switch (state->m_OperationMode) {
1801 case OM_QAM_ITU_A:
1802 case OM_QAM_ITU_B:
1803 case OM_QAM_ITU_C:
1804 status = GetQAMLockStatus(state, pLockStatus);
1805 break;
1806 case OM_DVBT:
1807 status = GetDVBTLockStatus(state, pLockStatus);
1808 break;
1809 default:
1810 break;
1811 }
1812 return status;
1813}
1814
1815static int MPEGTSStart(struct drxk_state *state)
1816{
1817 int status = 0;
1818
1819 u16 fecOcSncMode = 0;
1820
1821 do {
1822 /* Allow OC to sync again */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001823 status = Read16_0(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1824 if (status < 0)
1825 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001826 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001827 status = Write16_0(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1828 if (status < 0)
1829 break;
1830 status = Write16_0(state, FEC_OC_SNC_UNLOCK__A, 1);
1831 if (status < 0)
1832 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001833 } while (0);
1834 return status;
1835}
1836
1837static int MPEGTSDtoInit(struct drxk_state *state)
1838{
1839 int status = -1;
1840
1841 do {
1842 /* Rate integration settings */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001843 status = Write16_0(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1844 if (status < 0)
1845 break;
1846 status = Write16_0(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1847 if (status < 0)
1848 break;
1849 status = Write16_0(state, FEC_OC_RCN_GAIN__A, 0x000A);
1850 if (status < 0)
1851 break;
1852 status = Write16_0(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1853 if (status < 0)
1854 break;
1855 status = Write16_0(state, FEC_OC_AVR_PARM_B__A, 0x0006);
1856 if (status < 0)
1857 break;
1858 status = Write16_0(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
1859 if (status < 0)
1860 break;
1861 status = Write16_0(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
1862 if (status < 0)
1863 break;
1864 status = Write16_0(state, FEC_OC_TMD_COUNT__A, 0x03F4);
1865 if (status < 0)
1866 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001867
1868 /* Additional configuration */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001869 status = Write16_0(state, FEC_OC_OCR_INVERT__A, 0);
1870 if (status < 0)
1871 break;
1872 status = Write16_0(state, FEC_OC_SNC_LWM__A, 2);
1873 if (status < 0)
1874 break;
1875 status = Write16_0(state, FEC_OC_SNC_HWM__A, 12);
1876 if (status < 0)
1877 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001878 } while (0);
1879 return status;
1880}
1881
Oliver Endrissebc7de22011-07-03 13:49:44 -03001882static int MPEGTSDtoSetup(struct drxk_state *state,
1883 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001884{
1885 int status = -1;
1886
Oliver Endrissebc7de22011-07-03 13:49:44 -03001887 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
1888 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
1889 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
1890 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
1891 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
1892 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
1893 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001894 u16 fecOcTmdMode = 0;
1895 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001896 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001897 bool staticCLK = false;
1898
1899 do {
1900 /* Check insertion of the Reed-Solomon parity bytes */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001901 status = Read16_0(state, FEC_OC_MODE__A, &fecOcRegMode);
1902 if (status < 0)
1903 break;
1904 status = Read16_0(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
1905 if (status < 0)
1906 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001907 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001908 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
1909 if (state->m_insertRSByte == true) {
1910 /* enable parity symbol forward */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001911 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001912 /* MVAL disable during parity bytes */
1913 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
1914 /* TS burst length to 204 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001915 fecOcDtoBurstLen = 204;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001916 }
1917
1918 /* Check serial or parrallel output */
1919 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
1920 if (state->m_enableParallel == false) {
1921 /* MPEG data output is serial -> set ipr_mode[0] */
1922 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
1923 }
1924
1925 switch (oMode) {
1926 case OM_DVBT:
1927 maxBitRate = state->m_DVBTBitrate;
1928 fecOcTmdMode = 3;
1929 fecOcRcnCtlRate = 0xC00000;
1930 staticCLK = state->m_DVBTStaticCLK;
1931 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001932 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001933 case OM_QAM_ITU_C:
1934 fecOcTmdMode = 0x0004;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001935 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001936 maxBitRate = state->m_DVBCBitrate;
1937 staticCLK = state->m_DVBCStaticCLK;
1938 break;
1939 default:
1940 status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001941 } /* switch (standard) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001942 status = status;
1943 if (status < 0)
1944 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001945
1946 /* Configure DTO's */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001947 if (staticCLK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001948 u32 bitRate = 0;
1949
1950 /* Rational DTO for MCLK source (static MCLK rate),
1951 Dynamic DTO for optimal grouping
1952 (avoid intra-packet gaps),
1953 DTO offset enable to sync TS burst with MSTRT */
1954 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
1955 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
1956 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
1957 FEC_OC_FCT_MODE_VIRT_ENA__M);
1958
1959 /* Check user defined bitrate */
1960 bitRate = maxBitRate;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001961 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001962 bitRate = 75900000UL;
1963 }
1964 /* Rational DTO period:
1965 dto_period = (Fsys / bitrate) - 2
1966
1967 Result should be floored,
1968 to make sure >= requested bitrate
Oliver Endrissebc7de22011-07-03 13:49:44 -03001969 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001970 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
1971 * 1000) / bitRate);
1972 if (fecOcDtoPeriod <= 2)
1973 fecOcDtoPeriod = 0;
1974 else
1975 fecOcDtoPeriod -= 2;
1976 fecOcTmdIntUpdRate = 8;
1977 } else {
1978 /* (commonAttr->staticCLK == false) => dynamic mode */
1979 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
1980 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
1981 fecOcTmdIntUpdRate = 5;
1982 }
1983
1984 /* Write appropriate registers with requested configuration */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001985 status = Write16_0(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
1986 if (status < 0)
1987 break;
1988 status = Write16_0(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
1989 if (status < 0)
1990 break;
1991 status = Write16_0(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
1992 if (status < 0)
1993 break;
1994 status = Write16_0(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
1995 if (status < 0)
1996 break;
1997 status = Write16_0(state, FEC_OC_MODE__A, fecOcRegMode);
1998 if (status < 0)
1999 break;
2000 status = Write16_0(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2001 if (status < 0)
2002 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002003
2004 /* Rate integration settings */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002005 status = Write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate, 0);
2006 if (status < 0)
2007 break;
2008 status = Write16_0(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2009 if (status < 0)
2010 break;
2011 status = Write16_0(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2012 if (status < 0)
2013 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002014 } while (0);
2015 return status;
2016}
2017
2018static int MPEGTSConfigurePolarity(struct drxk_state *state)
2019{
2020 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002021 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002022
2023 /* Data mask for the output data byte */
2024 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002025 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2026 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2027 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2028 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002029
2030 /* Control selective inversion of output bits */
2031 fecOcRegIprInvert &= (~(InvertDataMask));
2032 if (state->m_invertDATA == true)
2033 fecOcRegIprInvert |= InvertDataMask;
2034 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2035 if (state->m_invertERR == true)
2036 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2037 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2038 if (state->m_invertSTR == true)
2039 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2040 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2041 if (state->m_invertVAL == true)
2042 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2043 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2044 if (state->m_invertCLK == true)
2045 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002046 status = Write16_0(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002047 return status;
2048}
2049
2050#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2051
2052static int SetAgcRf(struct drxk_state *state,
2053 struct SCfgAgc *pAgcCfg, bool isDTV)
2054{
2055 int status = 0;
2056 struct SCfgAgc *pIfAgcSettings;
2057
2058 if (pAgcCfg == NULL)
2059 return -1;
2060
2061 do {
2062 u16 data = 0;
2063
2064 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002065 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002066
2067 /* Enable RF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002068 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2069 if (status < 0)
2070 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002071 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002072 status = Write16_0(state, IQM_AF_STDBY__A, data);
2073 if (status < 0)
2074 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002075
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002076 status = Read16(state, SCU_RAM_AGC_CONFIG__A, &data, 0);
2077 if (status < 0)
2078 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002079
2080 /* Enable SCU RF AGC loop */
2081 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2082
2083 /* Polarity */
2084 if (state->m_RfAgcPol)
2085 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2086 else
2087 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002088 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2089 if (status < 0)
2090 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002091
2092 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002093 status = Read16(state, SCU_RAM_AGC_KI_RED__A, &data, 0);
2094 if (status < 0)
2095 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002096
2097 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2098 data |= (~(pAgcCfg->speed <<
2099 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2100 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2101
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002102 status = Write16_0(state, SCU_RAM_AGC_KI_RED__A, data);
2103 if (status < 0)
2104 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002105
2106 if (IsDVBT(state))
2107 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2108 else if (IsQAM(state))
2109 pIfAgcSettings = &state->m_qamIfAgcCfg;
2110 else
2111 pIfAgcSettings = &state->m_atvIfAgcCfg;
2112 if (pIfAgcSettings == NULL)
2113 return -1;
2114
2115 /* Set TOP, only if IF-AGC is in AUTO mode */
2116 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002117 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
2118 if (status < 0)
2119 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002120
2121 /* Cut-Off current */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002122 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2123 if (status < 0)
2124 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002125
2126 /* Max. output level */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002127 status = Write16_0(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2128 if (status < 0)
2129 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002130
2131 break;
2132
2133 case DRXK_AGC_CTRL_USER:
2134 /* Enable RF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002135 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2136 if (status < 0)
2137 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002138 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002139 status = Write16_0(state, IQM_AF_STDBY__A, data);
2140 if (status < 0)
2141 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002142
2143 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002144 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2145 if (status < 0)
2146 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002147 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2148 if (state->m_RfAgcPol)
2149 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2150 else
2151 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002152 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2153 if (status < 0)
2154 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002155
2156 /* SCU c.o.c. to 0, enabling full control range */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002157 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2158 if (status < 0)
2159 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002160
2161 /* Write value to output pin */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002162 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2163 if (status < 0)
2164 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002165 break;
2166
Oliver Endrissebc7de22011-07-03 13:49:44 -03002167 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002168 /* Disable RF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002169 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2170 if (status < 0)
2171 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002172 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002173 status = Write16_0(state, IQM_AF_STDBY__A, data);
2174 if (status < 0)
2175 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002176
2177 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002178 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2179 if (status < 0)
2180 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002181 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002182 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2183 if (status < 0)
2184 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002185 break;
2186
2187 default:
2188 return -1;
2189
Oliver Endrissebc7de22011-07-03 13:49:44 -03002190 } /* switch (agcsettings->ctrlMode) */
2191 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002192 return status;
2193}
2194
2195#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2196
Oliver Endrissebc7de22011-07-03 13:49:44 -03002197static int SetAgcIf(struct drxk_state *state,
2198 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002199{
2200 u16 data = 0;
2201 int status = 0;
2202 struct SCfgAgc *pRfAgcSettings;
2203
2204 do {
2205 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002206 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002207
2208 /* Enable IF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002209 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2210 if (status < 0)
2211 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002212 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002213 status = Write16_0(state, IQM_AF_STDBY__A, data);
2214 if (status < 0)
2215 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002216
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002217 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2218 if (status < 0)
2219 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002220
2221 /* Enable SCU IF AGC loop */
2222 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2223
2224 /* Polarity */
2225 if (state->m_IfAgcPol)
2226 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2227 else
2228 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002229 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2230 if (status < 0)
2231 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002232
2233 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002234 status = Read16_0(state, SCU_RAM_AGC_KI_RED__A, &data);
2235 if (status < 0)
2236 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002237 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2238 data |= (~(pAgcCfg->speed <<
2239 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2240 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2241
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002242 status = Write16_0(state, SCU_RAM_AGC_KI_RED__A, data);
2243 if (status < 0)
2244 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002245
2246 if (IsQAM(state))
2247 pRfAgcSettings = &state->m_qamRfAgcCfg;
2248 else
2249 pRfAgcSettings = &state->m_atvRfAgcCfg;
2250 if (pRfAgcSettings == NULL)
2251 return -1;
2252 /* Restore TOP */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002253 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2254 if (status < 0)
2255 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002256 break;
2257
Oliver Endrissebc7de22011-07-03 13:49:44 -03002258 case DRXK_AGC_CTRL_USER:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002259
2260 /* Enable IF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002261 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2262 if (status < 0)
2263 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002264 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002265 status = Write16_0(state, IQM_AF_STDBY__A, data);
2266 if (status < 0)
2267 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002268
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002269 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2270 if (status < 0)
2271 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002272
2273 /* Disable SCU IF AGC loop */
2274 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2275
2276 /* Polarity */
2277 if (state->m_IfAgcPol)
2278 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2279 else
2280 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002281 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2282 if (status < 0)
2283 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002284
2285 /* Write value to output pin */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002286 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2287 if (status < 0)
2288 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002289 break;
2290
Oliver Endrissebc7de22011-07-03 13:49:44 -03002291 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002292
2293 /* Disable If AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002294 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2295 if (status < 0)
2296 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002297 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002298 status = Write16_0(state, IQM_AF_STDBY__A, data);
2299 if (status < 0)
2300 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002301
2302 /* Disable SCU IF AGC loop */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002303 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2304 if (status < 0)
2305 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002306 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002307 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2308 if (status < 0)
2309 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002310 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002311 } /* switch (agcSettingsIf->ctrlMode) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002312
2313 /* always set the top to support
2314 configurations without if-loop */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002315 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2316 if (status < 0)
2317 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002318
2319
Oliver Endrissebc7de22011-07-03 13:49:44 -03002320 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002321 return status;
2322}
2323
2324static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2325{
2326 u16 agcDacLvl;
2327 int status = Read16_0(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2328
2329 *pValue = 0;
2330
Oliver Endrissebc7de22011-07-03 13:49:44 -03002331 if (status == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002332 u16 Level = 0;
2333 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2334 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2335 if (Level < 14000)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002336 *pValue = (14000 - Level) / 4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002337 else
2338 *pValue = 0;
2339 }
2340 return status;
2341}
2342
Oliver Endrissebc7de22011-07-03 13:49:44 -03002343static int GetQAMSignalToNoise(struct drxk_state *state,
2344 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002345{
2346 int status = 0;
2347
2348 do {
2349 /* MER calculation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002350 u16 qamSlErrPower = 0; /* accum. error between
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002351 raw and sliced symbols */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002352 u32 qamSlSigPower = 0; /* used for MER, depends of
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002353 QAM constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002354 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002355
2356 /* get the register value needed for MER */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002357 status = Read16_0(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2358 if (status < 0)
2359 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002360
Oliver Endrissebc7de22011-07-03 13:49:44 -03002361 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002362 case QAM_16:
2363 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2364 break;
2365 case QAM_32:
2366 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2367 break;
2368 case QAM_64:
2369 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2370 break;
2371 case QAM_128:
2372 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2373 break;
2374 default:
2375 case QAM_256:
2376 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2377 break;
2378 }
2379
2380 if (qamSlErrPower > 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002381 qamSlMer = Log10Times100(qamSlSigPower) -
2382 Log10Times100((u32) qamSlErrPower);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002383 }
2384 *pSignalToNoise = qamSlMer;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002385 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002386 return status;
2387}
2388
Oliver Endrissebc7de22011-07-03 13:49:44 -03002389static int GetDVBTSignalToNoise(struct drxk_state *state,
2390 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002391{
2392 int status = 0;
2393
Oliver Endrissebc7de22011-07-03 13:49:44 -03002394 u16 regData = 0;
2395 u32 EqRegTdSqrErrI = 0;
2396 u32 EqRegTdSqrErrQ = 0;
2397 u16 EqRegTdSqrErrExp = 0;
2398 u16 EqRegTdTpsPwrOfs = 0;
2399 u16 EqRegTdReqSmbCnt = 0;
2400 u32 tpsCnt = 0;
2401 u32 SqrErrIQ = 0;
2402 u32 a = 0;
2403 u32 b = 0;
2404 u32 c = 0;
2405 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002406 u16 transmissionParams = 0;
2407
2408 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002409 status = Read16_0(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2410 if (status < 0)
2411 break;
2412 status = Read16_0(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2413 if (status < 0)
2414 break;
2415 status = Read16_0(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2416 if (status < 0)
2417 break;
2418 status = Read16_0(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2419 if (status < 0)
2420 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002421 /* Extend SQR_ERR_I operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002422 EqRegTdSqrErrI = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002423 if ((EqRegTdSqrErrExp > 11) &&
2424 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2425 EqRegTdSqrErrI += 0x00010000UL;
2426 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002427 status = Read16_0(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2428 if (status < 0)
2429 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002430 /* Extend SQR_ERR_Q operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002431 EqRegTdSqrErrQ = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002432 if ((EqRegTdSqrErrExp > 11) &&
2433 (EqRegTdSqrErrQ < 0x00000FFFUL))
2434 EqRegTdSqrErrQ += 0x00010000UL;
2435
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002436 status = Read16_0(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2437 if (status < 0)
2438 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002439
2440 /* Check input data for MER */
2441
2442 /* MER calculation (in 0.1 dB) without math.h */
2443 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2444 iMER = 0;
2445 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2446 /* No error at all, this must be the HW reset value
2447 * Apparently no first measurement yet
2448 * Set MER to 0.0 */
2449 iMER = 0;
2450 } else {
2451 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03002452 EqRegTdSqrErrExp;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002453 if ((transmissionParams &
2454 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2455 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2456 tpsCnt = 17;
2457 else
2458 tpsCnt = 68;
2459
2460 /* IMER = 100 * log10 (x)
2461 where x = (EqRegTdTpsPwrOfs^2 *
2462 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2463
2464 => IMER = a + b -c
2465 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2466 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2467 c = 100 * log10 (SqrErrIQ)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002468 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002469
2470 /* log(x) x = 9bits * 9bits->18 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002471 a = Log10Times100(EqRegTdTpsPwrOfs *
2472 EqRegTdTpsPwrOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002473 /* log(x) x = 16bits * 7bits->23 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002474 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002475 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2476 c = Log10Times100(SqrErrIQ);
2477
2478 iMER = a + b;
2479 /* No negative MER, clip to zero */
2480 if (iMER > c)
2481 iMER -= c;
2482 else
2483 iMER = 0;
2484 }
2485 *pSignalToNoise = iMER;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002486 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002487
2488 return status;
2489}
2490
2491static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2492{
2493 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002494 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002495 case OM_DVBT:
2496 return GetDVBTSignalToNoise(state, pSignalToNoise);
2497 case OM_QAM_ITU_A:
2498 case OM_QAM_ITU_C:
2499 return GetQAMSignalToNoise(state, pSignalToNoise);
2500 default:
2501 break;
2502 }
2503 return 0;
2504}
2505
2506#if 0
2507static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2508{
2509 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2510 int status = 0;
2511
Oliver Endrissebc7de22011-07-03 13:49:44 -03002512 static s32 QE_SN[] = {
2513 51, /* QPSK 1/2 */
2514 69, /* QPSK 2/3 */
2515 79, /* QPSK 3/4 */
2516 89, /* QPSK 5/6 */
2517 97, /* QPSK 7/8 */
2518 108, /* 16-QAM 1/2 */
2519 131, /* 16-QAM 2/3 */
2520 146, /* 16-QAM 3/4 */
2521 156, /* 16-QAM 5/6 */
2522 160, /* 16-QAM 7/8 */
2523 165, /* 64-QAM 1/2 */
2524 187, /* 64-QAM 2/3 */
2525 202, /* 64-QAM 3/4 */
2526 216, /* 64-QAM 5/6 */
2527 225, /* 64-QAM 7/8 */
2528 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002529
2530 *pQuality = 0;
2531
2532 do {
2533 s32 SignalToNoise = 0;
2534 u16 Constellation = 0;
2535 u16 CodeRate = 0;
2536 u32 SignalToNoiseRel;
2537 u32 BERQuality;
2538
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002539 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2540 if (status < 0)
2541 break;
2542 status = Read16_0(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
2543 if (status < 0)
2544 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002545 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2546
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002547 status = Read16_0(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
2548 if (status < 0)
2549 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002550 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2551
2552 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2553 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2554 break;
2555 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002556 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002557 BERQuality = 100;
2558
Oliver Endrissebc7de22011-07-03 13:49:44 -03002559 if (SignalToNoiseRel < -70)
2560 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002561 else if (SignalToNoiseRel < 30)
2562 *pQuality = ((SignalToNoiseRel + 70) *
2563 BERQuality) / 100;
2564 else
2565 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002566 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002567 return 0;
2568};
2569
Oliver Endrissebc7de22011-07-03 13:49:44 -03002570static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002571{
2572 int status = 0;
2573 *pQuality = 0;
2574
2575 do {
2576 u32 SignalToNoise = 0;
2577 u32 BERQuality = 100;
2578 u32 SignalToNoiseRel = 0;
2579
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002580 status = GetQAMSignalToNoise(state, &SignalToNoise);
2581 if (status < 0)
2582 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002583
Oliver Endrissebc7de22011-07-03 13:49:44 -03002584 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002585 case QAM_16:
2586 SignalToNoiseRel = SignalToNoise - 200;
2587 break;
2588 case QAM_32:
2589 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002590 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002591 case QAM_64:
2592 SignalToNoiseRel = SignalToNoise - 260;
2593 break;
2594 case QAM_128:
2595 SignalToNoiseRel = SignalToNoise - 290;
2596 break;
2597 default:
2598 case QAM_256:
2599 SignalToNoiseRel = SignalToNoise - 320;
2600 break;
2601 }
2602
2603 if (SignalToNoiseRel < -70)
2604 *pQuality = 0;
2605 else if (SignalToNoiseRel < 30)
2606 *pQuality = ((SignalToNoiseRel + 70) *
2607 BERQuality) / 100;
2608 else
2609 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002610 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002611
2612 return status;
2613}
2614
2615static int GetQuality(struct drxk_state *state, s32 *pQuality)
2616{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002617 switch (state->m_OperationMode) {
2618 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002619 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002620 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002621 return GetDVBCQuality(state, pQuality);
2622 default:
2623 break;
2624 }
2625
2626 return 0;
2627}
2628#endif
2629
2630/* Free data ram in SIO HI */
2631#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2632#define SIO_HI_RA_RAM_USR_END__A 0x420060
2633
2634#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2635#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2636#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2637#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2638
2639#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2640#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2641#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2642
2643static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2644{
2645 int status;
2646
2647 if (state->m_DrxkState == DRXK_UNINITIALIZED)
2648 return -1;
2649 if (state->m_DrxkState == DRXK_POWERED_DOWN)
2650 return -1;
2651
2652 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002653 status = Write16_0(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2654 if (status < 0)
2655 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002656 if (bEnableBridge) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002657 status = Write16_0(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
2658 if (status < 0)
2659 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002660 } else {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002661 status = Write16_0(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2662 if (status < 0)
2663 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002664 }
2665
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002666 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2667 if (status < 0)
2668 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002669 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002670 return status;
2671}
2672
Oliver Endrissebc7de22011-07-03 13:49:44 -03002673static int SetPreSaw(struct drxk_state *state,
2674 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002675{
2676 int status;
2677
Oliver Endrissebc7de22011-07-03 13:49:44 -03002678 if ((pPreSawCfg == NULL)
2679 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002680 return -1;
2681
2682 status = Write16_0(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
2683 return status;
2684}
2685
2686static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002687 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002688{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002689 u16 blStatus = 0;
2690 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2691 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2692 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002693 unsigned long end;
2694
2695 mutex_lock(&state->mutex);
2696 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002697 status = Write16_0(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2698 if (status < 0)
2699 break;
2700 status = Write16_0(state, SIO_BL_TGT_HDR__A, blockbank);
2701 if (status < 0)
2702 break;
2703 status = Write16_0(state, SIO_BL_TGT_ADDR__A, offset);
2704 if (status < 0)
2705 break;
2706 status = Write16_0(state, SIO_BL_SRC_ADDR__A, romOffset);
2707 if (status < 0)
2708 break;
2709 status = Write16_0(state, SIO_BL_SRC_LEN__A, nrOfElements);
2710 if (status < 0)
2711 break;
2712 status = Write16_0(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2713 if (status < 0)
2714 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002715
Oliver Endrissebc7de22011-07-03 13:49:44 -03002716 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002717 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002718 status = Read16_0(state, SIO_BL_STATUS__A, &blStatus);
2719 if (status < 0)
2720 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002721 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002722 if (blStatus == 0x1) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002723 printk(KERN_ERR "SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002724 mutex_unlock(&state->mutex);
2725 return -1;
2726 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03002727 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002728 mutex_unlock(&state->mutex);
2729 return status;
2730
2731}
2732
Oliver Endrissebc7de22011-07-03 13:49:44 -03002733static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002734{
2735 u16 data = 0;
2736 int status;
2737
2738 do {
2739 /* Start measurement */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002740 status = Write16_0(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2741 if (status < 0)
2742 break;
2743 status = Write16_0(state, IQM_AF_START_LOCK__A, 1);
2744 if (status < 0)
2745 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002746
2747 *count = 0;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002748 status = Read16_0(state, IQM_AF_PHASE0__A, &data);
2749 if (status < 0)
2750 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002751 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002752 *count = *count + 1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002753 status = Read16_0(state, IQM_AF_PHASE1__A, &data);
2754 if (status < 0)
2755 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002756 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002757 *count = *count + 1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002758 status = Read16_0(state, IQM_AF_PHASE2__A, &data);
2759 if (status < 0)
2760 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002761 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002762 *count = *count + 1;
2763 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002764 return status;
2765}
2766
2767static int ADCSynchronization(struct drxk_state *state)
2768{
2769 u16 count = 0;
2770 int status;
2771
2772 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002773 status = ADCSyncMeasurement(state, &count);
2774 if (status < 0)
2775 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002776
Oliver Endrissebc7de22011-07-03 13:49:44 -03002777 if (count == 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002778 /* Try sampling on a diffrent edge */
2779 u16 clkNeg = 0;
2780
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002781 status = Read16_0(state, IQM_AF_CLKNEG__A, &clkNeg);
2782 if (status < 0)
2783 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002784 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002785 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2786 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2787 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002788 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002789 } else {
2790 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2791 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002792 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002793 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002794 status = Write16_0(state, IQM_AF_CLKNEG__A, clkNeg);
2795 if (status < 0)
2796 break;
2797 status = ADCSyncMeasurement(state, &count);
2798 if (status < 0)
2799 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002800 }
2801
2802 if (count < 2)
2803 status = -1;
2804 } while (0);
2805 return status;
2806}
2807
2808static int SetFrequencyShifter(struct drxk_state *state,
2809 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002810 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002811{
2812 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002813 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002814 u32 fmFrequencyShift = 0;
2815 bool tunerMirror = !state->m_bMirrorFreqSpect;
2816 u32 adcFreq;
2817 bool adcFlip;
2818 int status;
2819 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002820 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002821 u32 frequencyShift;
2822 bool imageToSelect;
2823
2824 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03002825 Program frequency shifter
2826 No need to account for mirroring on RF
2827 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002828 if (isDTV) {
2829 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
2830 (state->m_OperationMode == OM_QAM_ITU_C) ||
2831 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03002832 selectPosImage = true;
2833 else
2834 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002835 }
2836 if (tunerMirror)
2837 /* tuner doesn't mirror */
2838 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03002839 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002840 else
2841 /* tuner mirrors */
2842 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002843 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002844 if (ifFreqActual > samplingFrequency / 2) {
2845 /* adc mirrors */
2846 adcFreq = samplingFrequency - ifFreqActual;
2847 adcFlip = true;
2848 } else {
2849 /* adc doesn't mirror */
2850 adcFreq = ifFreqActual;
2851 adcFlip = false;
2852 }
2853
2854 frequencyShift = adcFreq;
2855 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03002856 adcFlip ^ selectPosImage;
2857 state->m_IqmFsRateOfs =
2858 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002859
2860 if (imageToSelect)
2861 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
2862
2863 /* Program frequency shifter with tuner offset compensation */
2864 /* frequencyShift += tunerFreqOffset; TODO */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002865 status = Write32(state, IQM_FS_RATE_OFS_LO__A,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002866 state->m_IqmFsRateOfs, 0);
2867 return status;
2868}
2869
2870static int InitAGC(struct drxk_state *state, bool isDTV)
2871{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002872 u16 ingainTgt = 0;
2873 u16 ingainTgtMin = 0;
2874 u16 ingainTgtMax = 0;
2875 u16 clpCyclen = 0;
2876 u16 clpSumMin = 0;
2877 u16 clpDirTo = 0;
2878 u16 snsSumMin = 0;
2879 u16 snsSumMax = 0;
2880 u16 clpSumMax = 0;
2881 u16 snsDirTo = 0;
2882 u16 kiInnergainMin = 0;
2883 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002884 u16 ifIaccuHiTgtMin = 0;
2885 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002886 u16 data = 0;
2887 u16 fastClpCtrlDelay = 0;
2888 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002889 int status = 0;
2890
2891 do {
2892 /* Common settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002893 snsSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002894 ifIaccuHiTgtMin = 2047;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002895 clpCyclen = 500;
2896 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002897
2898 if (IsQAM(state)) {
2899 /* Standard specific settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002900 clpSumMin = 8;
2901 clpDirTo = (u16) -9;
2902 clpCtrlMode = 0;
2903 snsSumMin = 8;
2904 snsDirTo = (u16) -9;
2905 kiInnergainMin = (u16) -1030;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002906 } else
2907 status = -1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002908 status = (status);
2909 if (status < 0)
2910 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002911 if (IsQAM(state)) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002912 ifIaccuHiTgtMax = 0x2380;
2913 ifIaccuHiTgt = 0x2380;
2914 ingainTgtMin = 0x0511;
2915 ingainTgt = 0x0511;
2916 ingainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002917 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002918 state->m_qamIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002919 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002920 ifIaccuHiTgtMax = 0x1200;
2921 ifIaccuHiTgt = 0x1200;
2922 ingainTgtMin = 13424;
2923 ingainTgt = 13424;
2924 ingainTgtMax = 30000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002925 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002926 state->m_dvbtIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002927 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002928 status = Write16_0(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
2929 if (status < 0)
2930 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002931
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002932 status = Write16_0(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
2933 if (status < 0)
2934 break;
2935 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
2936 if (status < 0)
2937 break;
2938 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
2939 if (status < 0)
2940 break;
2941 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
2942 if (status < 0)
2943 break;
2944 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
2945 if (status < 0)
2946 break;
2947 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
2948 if (status < 0)
2949 break;
2950 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
2951 if (status < 0)
2952 break;
2953 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
2954 if (status < 0)
2955 break;
2956 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
2957 if (status < 0)
2958 break;
2959 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
2960 if (status < 0)
2961 break;
2962 status = Write16_0(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
2963 if (status < 0)
2964 break;
2965 status = Write16_0(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
2966 if (status < 0)
2967 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002968
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002969 status = Write16_0(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
2970 if (status < 0)
2971 break;
2972 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
2973 if (status < 0)
2974 break;
2975 status = Write16_0(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
2976 if (status < 0)
2977 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002978
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002979 status = Write16_0(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
2980 if (status < 0)
2981 break;
2982 status = Write16_0(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
2983 if (status < 0)
2984 break;
2985 status = Write16_0(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
2986 if (status < 0)
2987 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002988
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002989 status = Write16_0(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
2990 if (status < 0)
2991 break;
2992 status = Write16_0(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
2993 if (status < 0)
2994 break;
2995 status = Write16_0(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
2996 if (status < 0)
2997 break;
2998 status = Write16_0(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
2999 if (status < 0)
3000 break;
3001 status = Write16_0(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3002 if (status < 0)
3003 break;
3004 status = Write16_0(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3005 if (status < 0)
3006 break;
3007 status = Write16_0(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3008 if (status < 0)
3009 break;
3010 status = Write16_0(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3011 if (status < 0)
3012 break;
3013 status = Write16_0(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3014 if (status < 0)
3015 break;
3016 status = Write16_0(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3017 if (status < 0)
3018 break;
3019 status = Write16_0(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3020 if (status < 0)
3021 break;
3022 status = Write16_0(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3023 if (status < 0)
3024 break;
3025 status = Write16_0(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3026 if (status < 0)
3027 break;
3028 status = Write16_0(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3029 if (status < 0)
3030 break;
3031 status = Write16_0(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3032 if (status < 0)
3033 break;
3034 status = Write16_0(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3035 if (status < 0)
3036 break;
3037 status = Write16_0(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3038 if (status < 0)
3039 break;
3040 status = Write16_0(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3041 if (status < 0)
3042 break;
3043 status = Write16_0(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3044 if (status < 0)
3045 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003046
3047 /* Initialize inner-loop KI gain factors */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003048 status = Read16_0(state, SCU_RAM_AGC_KI__A, &data);
3049 if (status < 0)
3050 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003051 if (IsQAM(state)) {
3052 data = 0x0657;
3053 data &= ~SCU_RAM_AGC_KI_RF__M;
3054 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3055 data &= ~SCU_RAM_AGC_KI_IF__M;
3056 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3057 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003058 status = Write16_0(state, SCU_RAM_AGC_KI__A, data);
3059 if (status < 0)
3060 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003061 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003062 return status;
3063}
3064
Oliver Endrissebc7de22011-07-03 13:49:44 -03003065static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003066{
3067 int status;
3068
3069 do {
3070 if (packetErr == NULL) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003071 status = Write16_0(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3072 if (status < 0)
3073 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003074 } else {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003075 status = Read16_0(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3076 if (status < 0)
3077 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003078 }
3079 } while (0);
3080 return status;
3081}
3082
3083static int DVBTScCommand(struct drxk_state *state,
3084 u16 cmd, u16 subcmd,
3085 u16 param0, u16 param1, u16 param2,
3086 u16 param3, u16 param4)
3087{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003088 u16 curCmd = 0;
3089 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003090 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003091 u16 scExec = 0;
3092 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003093
3094 status = Read16_0(state, OFDM_SC_COMM_EXEC__A, &scExec);
3095 if (scExec != 1) {
3096 /* SC is not running */
3097 return -1;
3098 }
3099
3100 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003101 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003102 do {
3103 msleep(1);
3104 status = Read16_0(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
3105 retryCnt++;
3106 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
3107 if (retryCnt >= DRXK_MAX_RETRIES)
3108 return -1;
3109 /* Write sub-command */
3110 switch (cmd) {
3111 /* All commands using sub-cmd */
3112 case OFDM_SC_RA_RAM_CMD_PROC_START:
3113 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3114 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003115 status =
3116 Write16_0(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003117 break;
3118 default:
3119 /* Do nothing */
3120 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003121 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003122
3123 /* Write needed parameters and the command */
3124 switch (cmd) {
3125 /* All commands using 5 parameters */
3126 /* All commands using 4 parameters */
3127 /* All commands using 3 parameters */
3128 /* All commands using 2 parameters */
3129 case OFDM_SC_RA_RAM_CMD_PROC_START:
3130 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3131 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003132 status =
3133 Write16_0(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003134 /* All commands using 1 parameters */
3135 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3136 case OFDM_SC_RA_RAM_CMD_USER_IO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003137 status =
3138 Write16_0(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003139 /* All commands using 0 parameters */
3140 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3141 case OFDM_SC_RA_RAM_CMD_NULL:
3142 /* Write command */
3143 status = Write16_0(state, OFDM_SC_RA_RAM_CMD__A, cmd);
3144 break;
3145 default:
3146 /* Unknown command */
3147 return -EINVAL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003148 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003149
3150 /* Wait until sc is ready processing command */
3151 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003152 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003153 msleep(1);
3154 status = Read16_0(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
3155 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003156 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003157 if (retryCnt >= DRXK_MAX_RETRIES)
3158 return -1;
3159
3160 /* Check for illegal cmd */
3161 status = Read16_0(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003162 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003163 /* illegal command */
3164 return -EINVAL;
3165 }
3166
3167 /* Retreive results parameters from SC */
3168 switch (cmd) {
3169 /* All commands yielding 5 results */
3170 /* All commands yielding 4 results */
3171 /* All commands yielding 3 results */
3172 /* All commands yielding 2 results */
3173 /* All commands yielding 1 result */
3174 case OFDM_SC_RA_RAM_CMD_USER_IO:
3175 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003176 status =
3177 Read16_0(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003178 /* All commands yielding 0 results */
3179 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3180 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3181 case OFDM_SC_RA_RAM_CMD_PROC_START:
3182 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3183 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3184 case OFDM_SC_RA_RAM_CMD_NULL:
3185 break;
3186 default:
3187 /* Unknown command */
3188 return -EINVAL;
3189 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003190 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003191 return status;
3192}
3193
Oliver Endrissebc7de22011-07-03 13:49:44 -03003194static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003195{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003196 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003197 int status;
3198
3199 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003200 status = CtrlPowerMode(state, &powerMode);
3201 if (status < 0)
3202 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003203 } while (0);
3204 return status;
3205}
3206
Oliver Endrissebc7de22011-07-03 13:49:44 -03003207static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003208{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003209 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003210
3211 if (*enabled == true)
3212 status = Write16_0(state, IQM_CF_BYPASSDET__A, 0);
3213 else
3214 status = Write16_0(state, IQM_CF_BYPASSDET__A, 1);
3215
3216 return status;
3217}
3218
3219#define DEFAULT_FR_THRES_8K 4000
3220static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3221{
3222
3223 int status;
3224
3225 if (*enabled == true) {
3226 /* write mask to 1 */
3227 status = Write16_0(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
3228 DEFAULT_FR_THRES_8K);
3229 } else {
3230 /* write mask to 0 */
3231 status = Write16_0(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
3232 }
3233
3234 return status;
3235}
3236
3237static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3238 struct DRXKCfgDvbtEchoThres_t *echoThres)
3239{
3240 u16 data = 0;
3241 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003242
3243 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003244 status = Read16_0(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3245 if (status < 0)
3246 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003247
Oliver Endrissebc7de22011-07-03 13:49:44 -03003248 switch (echoThres->fftMode) {
3249 case DRX_FFTMODE_2K:
3250 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3251 data |=
3252 ((echoThres->threshold <<
3253 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3254 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3255 break;
3256 case DRX_FFTMODE_8K:
3257 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3258 data |=
3259 ((echoThres->threshold <<
3260 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3261 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3262 break;
3263 default:
3264 return -1;
3265 break;
3266 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003267
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003268 status = Write16_0(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3269 if (status < 0)
3270 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003271 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003272
Oliver Endrissebc7de22011-07-03 13:49:44 -03003273 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003274}
3275
3276static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003277 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003278{
3279 int status;
3280
3281 switch (*speed) {
3282 case DRXK_DVBT_SQI_SPEED_FAST:
3283 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3284 case DRXK_DVBT_SQI_SPEED_SLOW:
3285 break;
3286 default:
3287 return -EINVAL;
3288 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03003289 status = Write16_0(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
3290 (u16) *speed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003291 return status;
3292}
3293
3294/*============================================================================*/
3295
3296/**
3297* \brief Activate DVBT specific presets
3298* \param demod instance of demodulator.
3299* \return DRXStatus_t.
3300*
3301* Called in DVBTSetStandard
3302*
3303*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003304static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003305{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003306 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003307
Oliver Endrissebc7de22011-07-03 13:49:44 -03003308 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3309 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003310
Oliver Endrissebc7de22011-07-03 13:49:44 -03003311 do {
3312 bool setincenable = false;
3313 bool setfrenable = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003314 status = DVBTCtrlSetIncEnable(state, &setincenable);
3315 if (status < 0)
3316 break;
3317 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3318 if (status < 0)
3319 break;
3320 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3321 if (status < 0)
3322 break;
3323 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3324 if (status < 0)
3325 break;
3326 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3327 if (status < 0)
3328 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003329 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003330
Oliver Endrissebc7de22011-07-03 13:49:44 -03003331 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003332}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003333
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003334/*============================================================================*/
3335
3336/**
3337* \brief Initialize channelswitch-independent settings for DVBT.
3338* \param demod instance of demodulator.
3339* \return DRXStatus_t.
3340*
3341* For ROM code channel filter taps are loaded from the bootloader. For microcode
3342* the DVB-T taps from the drxk_filters.h are used.
3343*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003344static int SetDVBTStandard(struct drxk_state *state,
3345 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003346{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003347 u16 cmdResult = 0;
3348 u16 data = 0;
3349 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003350
3351 PowerUpDVBT(state);
3352
3353 do {
3354 /* added antenna switch */
3355 SwitchAntennaToDVBT(state);
3356 /* send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003357 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
3358 if (status < 0)
3359 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003360
3361 /* send OFDM setenv command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003362 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3363 if (status < 0)
3364 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003365
3366 /* reset datapath for OFDM, processors first */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003367 status = Write16_0(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3368 if (status < 0)
3369 break;
3370 status = Write16_0(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3371 if (status < 0)
3372 break;
3373 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3374 if (status < 0)
3375 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003376
3377 /* IQM setup */
3378 /* synchronize on ofdstate->m_festart */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003379 status = Write16_0(state, IQM_AF_UPD_SEL__A, 1);
3380 if (status < 0)
3381 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003382 /* window size for clipping ADC detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003383 status = Write16_0(state, IQM_AF_CLP_LEN__A, 0);
3384 if (status < 0)
3385 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003386 /* window size for for sense pre-SAW detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003387 status = Write16_0(state, IQM_AF_SNS_LEN__A, 0);
3388 if (status < 0)
3389 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003390 /* sense threshold for sense pre-SAW detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003391 status = Write16_0(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3392 if (status < 0)
3393 break;
3394 status = SetIqmAf(state, true);
3395 if (status < 0)
3396 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003397
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003398 status = Write16_0(state, IQM_AF_AGC_RF__A, 0);
3399 if (status < 0)
3400 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003401
3402 /* Impulse noise cruncher setup */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003403 status = Write16_0(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3404 if (status < 0)
3405 break;
3406 status = Write16_0(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3407 if (status < 0)
3408 break;
3409 status = Write16_0(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3410 if (status < 0)
3411 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003412
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003413 status = Write16_0(state, IQM_RC_STRETCH__A, 16);
3414 if (status < 0)
3415 break;
3416 status = Write16_0(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3417 if (status < 0)
3418 break;
3419 status = Write16_0(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3420 if (status < 0)
3421 break;
3422 status = Write16_0(state, IQM_CF_SCALE__A, 1600);
3423 if (status < 0)
3424 break;
3425 status = Write16_0(state, IQM_CF_SCALE_SH__A, 0);
3426 if (status < 0)
3427 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003428
3429 /* virtual clipping threshold for clipping ADC detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003430 status = Write16_0(state, IQM_AF_CLP_TH__A, 448);
3431 if (status < 0)
3432 break;
3433 status = Write16_0(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3434 if (status < 0)
3435 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003436
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003437 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3438 if (status < 0)
3439 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003440
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003441 status = Write16_0(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3442 if (status < 0)
3443 break;
3444 status = Write16_0(state, IQM_CF_POW_MEAS_LEN__A, 2);
3445 if (status < 0)
3446 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003447 /* enable power measurement interrupt */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003448 status = Write16_0(state, IQM_CF_COMM_INT_MSK__A, 1);
3449 if (status < 0)
3450 break;
3451 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3452 if (status < 0)
3453 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003454
3455 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003456 status = ADCSynchronization(state);
3457 if (status < 0)
3458 break;
3459 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3460 if (status < 0)
3461 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003462
3463 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003464 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3465 if (status < 0)
3466 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003467
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003468 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3469 if (status < 0)
3470 break;
3471 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3472 if (status < 0)
3473 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003474
3475 /* Set Noise Estimation notch width and enable DC fix */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003476 status = Read16_0(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3477 if (status < 0)
3478 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003479 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003480 status = Write16_0(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3481 if (status < 0)
3482 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003483
3484 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003485 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3486 if (status < 0)
3487 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003488
Oliver Endrissebc7de22011-07-03 13:49:44 -03003489 if (!state->m_DRXK_A3_ROM_CODE) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003490 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003491 status = Write16_0(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3492 if (status < 0)
3493 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003494 }
3495
3496 /* OFDM_SC setup */
3497#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003498 status = Write16_0(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3499 if (status < 0)
3500 break;
3501 status = Write16_0(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3502 if (status < 0)
3503 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003504#endif
3505
3506 /* FEC setup */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003507 status = Write16_0(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3508 if (status < 0)
3509 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003510
3511
3512#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003513 status = Write16_0(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3514 if (status < 0)
3515 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003516#else
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003517 status = Write16_0(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3518 if (status < 0)
3519 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003520#endif
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003521 status = Write16_0(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3522 if (status < 0)
3523 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003524
3525 /* Setup MPEG bus */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003526 status = MPEGTSDtoSetup(state, OM_DVBT);
3527 if (status < 0)
3528 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003529 /* Set DVBT Presets */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003530 status = DVBTActivatePresets(state);
3531 if (status < 0)
3532 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003533
3534 } while (0);
3535
Oliver Endrissebc7de22011-07-03 13:49:44 -03003536 if (status < 0)
3537 printk(KERN_ERR "%s status - %08x\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003538
3539 return status;
3540}
3541
3542/*============================================================================*/
3543/**
3544* \brief Start dvbt demodulating for channel.
3545* \param demod instance of demodulator.
3546* \return DRXStatus_t.
3547*/
3548static int DVBTStart(struct drxk_state *state)
3549{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003550 u16 param1;
3551 int status;
3552 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003553
Oliver Endrissebc7de22011-07-03 13:49:44 -03003554 /* Start correct processes to get in lock */
3555 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
3556 do {
3557 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003558 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3559 if (status < 0)
3560 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003561 /* Start FEC OC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003562 status = MPEGTSStart(state);
3563 if (status < 0)
3564 break;
3565 status = Write16_0(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3566 if (status < 0)
3567 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003568 } while (0);
3569 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003570}
3571
3572
3573/*============================================================================*/
3574
3575/**
3576* \brief Set up dvbt demodulator for channel.
3577* \param demod instance of demodulator.
3578* \return DRXStatus_t.
3579* // original DVBTSetChannel()
3580*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003581static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3582 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003583{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003584 u16 cmdResult = 0;
3585 u16 transmissionParams = 0;
3586 u16 operationMode = 0;
3587 u32 iqmRcRateOfs = 0;
3588 u32 bandwidth = 0;
3589 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003590 int status;
3591
Oliver Endrissebc7de22011-07-03 13:49:44 -03003592 /* printk(KERN_DEBUG "%s IF =%d, TFO = %d\n", __func__, IntermediateFreqkHz, tunerFreqOffset); */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003593 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003594 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3595 if (status < 0)
3596 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003597
3598 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003599 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3600 if (status < 0)
3601 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003602
3603 /* Stop processors */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003604 status = Write16_0(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3605 if (status < 0)
3606 break;
3607 status = Write16_0(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3608 if (status < 0)
3609 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003610
3611 /* Mandatory fix, always stop CP, required to set spl offset back to
3612 hardware default (is set to 0 by ucode during pilot detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003613 status = Write16_0(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3614 if (status < 0)
3615 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003616
3617 /*== Write channel settings to device =====================================*/
3618
3619 /* mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003620 switch (state->param.u.ofdm.transmission_mode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003621 case TRANSMISSION_MODE_AUTO:
3622 default:
3623 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3624 /* fall through , try first guess DRX_FFTMODE_8K */
3625 case TRANSMISSION_MODE_8K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003626 transmissionParams |=
3627 OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003628 break;
3629 case TRANSMISSION_MODE_2K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003630 transmissionParams |=
3631 OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003632 break;
3633 }
3634
3635 /* guard */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003636 switch (state->param.u.ofdm.guard_interval) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003637 default:
3638 case GUARD_INTERVAL_AUTO:
3639 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3640 /* fall through , try first guess DRX_GUARD_1DIV4 */
3641 case GUARD_INTERVAL_1_4:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003642 transmissionParams |=
3643 OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003644 break;
3645 case GUARD_INTERVAL_1_32:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003646 transmissionParams |=
3647 OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003648 break;
3649 case GUARD_INTERVAL_1_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003650 transmissionParams |=
3651 OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003652 break;
3653 case GUARD_INTERVAL_1_8:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003654 transmissionParams |=
3655 OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003656 break;
3657 }
3658
3659 /* hierarchy */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003660 switch (state->param.u.ofdm.hierarchy_information) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003661 case HIERARCHY_AUTO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003662 case HIERARCHY_NONE:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003663 default:
3664 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3665 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003666 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3667 /* break; */
3668 case HIERARCHY_1:
3669 transmissionParams |=
3670 OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003671 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003672 case HIERARCHY_2:
3673 transmissionParams |=
3674 OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003675 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003676 case HIERARCHY_4:
3677 transmissionParams |=
3678 OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003679 break;
3680 }
3681
3682
3683 /* constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003684 switch (state->param.u.ofdm.constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003685 case QAM_AUTO:
3686 default:
3687 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3688 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3689 case QAM_64:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003690 transmissionParams |=
3691 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003692 break;
3693 case QPSK:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003694 transmissionParams |=
3695 OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003696 break;
3697 case QAM_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003698 transmissionParams |=
3699 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003700 break;
3701 }
3702#if 0
Oliver Endrissebc7de22011-07-03 13:49:44 -03003703 /* No hierachical channels support in BDA */
3704 /* Priority (only for hierarchical channels) */
3705 switch (channel->priority) {
3706 case DRX_PRIORITY_LOW:
3707 transmissionParams |=
3708 OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3709 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3710 OFDM_EC_SB_PRIOR_LO);
3711 break;
3712 case DRX_PRIORITY_HIGH:
3713 transmissionParams |=
3714 OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3715 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3716 OFDM_EC_SB_PRIOR_HI));
3717 break;
3718 case DRX_PRIORITY_UNKNOWN: /* fall through */
3719 default:
3720 return DRX_STS_INVALID_ARG;
3721 break;
3722 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003723#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03003724 /* Set Priorty high */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003725 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003726 status = Write16_0(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3727 if (status < 0)
3728 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003729#endif
3730
3731 /* coderate */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003732 switch (state->param.u.ofdm.code_rate_HP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003733 case FEC_AUTO:
3734 default:
3735 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3736 /* fall through , try first guess DRX_CODERATE_2DIV3 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003737 case FEC_2_3:
3738 transmissionParams |=
3739 OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003740 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003741 case FEC_1_2:
3742 transmissionParams |=
3743 OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003744 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003745 case FEC_3_4:
3746 transmissionParams |=
3747 OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003748 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003749 case FEC_5_6:
3750 transmissionParams |=
3751 OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003752 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003753 case FEC_7_8:
3754 transmissionParams |=
3755 OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003756 break;
3757 }
3758
3759 /* SAW filter selection: normaly not necesarry, but if wanted
3760 the application can select a SAW filter via the driver by using UIOs */
3761 /* First determine real bandwidth (Hz) */
3762 /* Also set delay for impulse noise cruncher */
3763 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3764 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3765 functions */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003766 switch (state->param.u.ofdm.bandwidth) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003767 case BANDWIDTH_AUTO:
3768 case BANDWIDTH_8_MHZ:
3769 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003770 status = Write16_0(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
3771 if (status < 0)
3772 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003773 /* cochannel protection for PAL 8 MHz */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003774 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3775 if (status < 0)
3776 break;
3777 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3778 if (status < 0)
3779 break;
3780 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3781 if (status < 0)
3782 break;
3783 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3784 if (status < 0)
3785 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003786 break;
3787 case BANDWIDTH_7_MHZ:
3788 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003789 status = Write16_0(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3790 if (status < 0)
3791 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003792 /* cochannel protection for PAL 7 MHz */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003793 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3794 if (status < 0)
3795 break;
3796 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3797 if (status < 0)
3798 break;
3799 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3800 if (status < 0)
3801 break;
3802 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3803 if (status < 0)
3804 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003805 break;
3806 case BANDWIDTH_6_MHZ:
3807 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003808 status = Write16_0(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3809 if (status < 0)
3810 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003811 /* cochannel protection for NTSC 6 MHz */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003812 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3813 if (status < 0)
3814 break;
3815 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3816 if (status < 0)
3817 break;
3818 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3819 if (status < 0)
3820 break;
3821 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3822 if (status < 0)
3823 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003824 break;
Mauro Carvalho Chehabe16cede2011-07-03 18:18:14 -03003825 default:
3826 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003827 }
3828
Oliver Endrissebc7de22011-07-03 13:49:44 -03003829 if (iqmRcRateOfs == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003830 /* Now compute IQM_RC_RATE_OFS
3831 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3832 =>
3833 ((SysFreq / BandWidth) * (2^21)) - (2^23)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003834 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003835 /* (SysFreq / BandWidth) * (2^28) */
3836 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
3837 => assert(MAX(sysClk) < 16*MIN(bandwidth))
3838 => assert(109714272 > 48000000) = true so Frac 28 can be used */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003839 iqmRcRateOfs = Frac28a((u32)
3840 ((state->m_sysClockFreq *
3841 1000) / 3), bandwidth);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003842 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
3843 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003844 iqmRcRateOfs += 0x80L;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003845 iqmRcRateOfs = iqmRcRateOfs >> 7;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003846 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003847 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003848 }
3849
Oliver Endrissebc7de22011-07-03 13:49:44 -03003850 iqmRcRateOfs &=
3851 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
3852 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003853 status = Write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs, 0);
3854 if (status < 0)
3855 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003856
3857 /* Bandwidth setting done */
3858
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003859#if 0
3860 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
3861 if (status < 0)
3862 break;
3863#endif
3864 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
3865 if (status < 0)
3866 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003867
3868 /*== Start SC, write channel settings to SC ===============================*/
3869
3870 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003871 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3872 if (status < 0)
3873 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003874
3875 /* Enable SC after setting all other parameters */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003876 status = Write16_0(state, OFDM_SC_COMM_STATE__A, 0);
3877 if (status < 0)
3878 break;
3879 status = Write16_0(state, OFDM_SC_COMM_EXEC__A, 1);
3880 if (status < 0)
3881 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003882
3883
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003884 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
3885 if (status < 0)
3886 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003887
3888 /* Write SC parameter registers, set all AUTO flags in operation mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003889 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
3890 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
3891 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
3892 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
3893 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
3894 status =
3895 DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
3896 0, transmissionParams, param1, 0, 0, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003897 if (!state->m_DRXK_A3_ROM_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003898 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
3899 if (status < 0)
3900 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003901
Oliver Endrissebc7de22011-07-03 13:49:44 -03003902 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003903
3904 return status;
3905}
3906
3907
3908/*============================================================================*/
3909
3910/**
3911* \brief Retreive lock status .
3912* \param demod Pointer to demodulator instance.
3913* \param lockStat Pointer to lock status structure.
3914* \return DRXStatus_t.
3915*
3916*/
3917static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
3918{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003919 int status;
3920 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
3921 OFDM_SC_RA_RAM_LOCK_FEC__M);
3922 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
3923 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003924
Oliver Endrissebc7de22011-07-03 13:49:44 -03003925 u16 ScRaRamLock = 0;
3926 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003927
Oliver Endrissebc7de22011-07-03 13:49:44 -03003928 /* driver 0.9.0 */
3929 /* Check if SC is running */
3930 status = Read16_0(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
3931 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP) {
3932 /* SC not active; return DRX_NOT_LOCKED */
3933 *pLockStatus = NOT_LOCKED;
3934 return status;
3935 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003936
Oliver Endrissebc7de22011-07-03 13:49:44 -03003937 status = Read16_0(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003938
Oliver Endrissebc7de22011-07-03 13:49:44 -03003939 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
3940 *pLockStatus = MPEG_LOCK;
3941 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
3942 *pLockStatus = FEC_LOCK;
3943 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
3944 *pLockStatus = DEMOD_LOCK;
3945 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
3946 *pLockStatus = NEVER_LOCK;
3947 else
3948 *pLockStatus = NOT_LOCKED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003949
Oliver Endrissebc7de22011-07-03 13:49:44 -03003950 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003951}
3952
Oliver Endrissebc7de22011-07-03 13:49:44 -03003953static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003954{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003955 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
3956 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003957
Oliver Endrissebc7de22011-07-03 13:49:44 -03003958 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003959 status = CtrlPowerMode(state, &powerMode);
3960 if (status < 0)
3961 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003962
Oliver Endrissebc7de22011-07-03 13:49:44 -03003963 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003964
Oliver Endrissebc7de22011-07-03 13:49:44 -03003965 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003966}
3967
3968
Oliver Endrissebc7de22011-07-03 13:49:44 -03003969/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003970static int PowerDownQAM(struct drxk_state *state)
3971{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003972 u16 data = 0;
3973 u16 cmdResult;
3974 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003975
Oliver Endrissebc7de22011-07-03 13:49:44 -03003976 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003977 status = Read16_0(state, SCU_COMM_EXEC__A, &data);
3978 if (status < 0)
3979 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003980 if (data == SCU_COMM_EXEC_ACTIVE) {
3981 /*
3982 STOP demodulator
3983 QAM and HW blocks
3984 */
3985 /* stop all comstate->m_exec */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003986 status = Write16_0(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
3987 if (status < 0)
3988 break;
3989 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3990 if (status < 0)
3991 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003992 }
3993 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003994 status = SetIqmAf(state, false);
3995 if (status < 0)
3996 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003997 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003998
Oliver Endrissebc7de22011-07-03 13:49:44 -03003999 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004000}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004001
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004002/*============================================================================*/
4003
4004/**
4005* \brief Setup of the QAM Measurement intervals for signal quality
4006* \param demod instance of demod.
4007* \param constellation current constellation.
4008* \return DRXStatus_t.
4009*
4010* NOTE:
4011* Take into account that for certain settings the errorcounters can overflow.
4012* The implementation does not check this.
4013*
4014*/
4015static int SetQAMMeasurement(struct drxk_state *state,
4016 enum EDrxkConstellation constellation,
4017 u32 symbolRate)
4018{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004019 u32 fecBitsDesired = 0; /* BER accounting period */
4020 u32 fecRsPeriodTotal = 0; /* Total period */
4021 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4022 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004023 int status = 0;
4024
Oliver Endrissebc7de22011-07-03 13:49:44 -03004025 fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004026
4027 do {
4028
4029 /* fecBitsDesired = symbolRate [kHz] *
4030 FrameLenght [ms] *
4031 (constellation + 1) *
4032 SyncLoss (== 1) *
4033 ViterbiLoss (==1)
Oliver Endrissebc7de22011-07-03 13:49:44 -03004034 */
4035 switch (constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004036 case DRX_CONSTELLATION_QAM16:
4037 fecBitsDesired = 4 * symbolRate;
4038 break;
4039 case DRX_CONSTELLATION_QAM32:
4040 fecBitsDesired = 5 * symbolRate;
4041 break;
4042 case DRX_CONSTELLATION_QAM64:
4043 fecBitsDesired = 6 * symbolRate;
4044 break;
4045 case DRX_CONSTELLATION_QAM128:
4046 fecBitsDesired = 7 * symbolRate;
4047 break;
4048 case DRX_CONSTELLATION_QAM256:
4049 fecBitsDesired = 8 * symbolRate;
4050 break;
4051 default:
4052 status = -EINVAL;
4053 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004054 status = status;
4055 if (status < 0)
4056 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004057
Oliver Endrissebc7de22011-07-03 13:49:44 -03004058 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4059 fecBitsDesired *= 500; /* meas. period [ms] */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004060
4061 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4062 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004063 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004064
4065 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4066 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4067 if (fecRsPrescale == 0) {
4068 /* Divide by zero (though impossible) */
4069 status = -1;
4070 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004071 status = status;
4072 if (status < 0)
4073 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004074 fecRsPeriod =
4075 ((u16) fecRsPeriodTotal +
4076 (fecRsPrescale >> 1)) / fecRsPrescale;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004077
4078 /* write corresponding registers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004079 status = Write16_0(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4080 if (status < 0)
4081 break;
4082 status = Write16_0(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4083 if (status < 0)
4084 break;
4085 status = Write16_0(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4086 if (status < 0)
4087 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004088
4089 } while (0);
4090
Oliver Endrissebc7de22011-07-03 13:49:44 -03004091 if (status < 0)
4092 printk(KERN_ERR "%s: status - %08x\n", __func__, status);
4093
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004094 return status;
4095}
4096
Oliver Endrissebc7de22011-07-03 13:49:44 -03004097static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004098{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004099 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004100
Oliver Endrissebc7de22011-07-03 13:49:44 -03004101 do {
4102 /* QAM Equalizer Setup */
4103 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004104 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4105 if (status < 0)
4106 break;
4107 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4108 if (status < 0)
4109 break;
4110 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4111 if (status < 0)
4112 break;
4113 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4114 if (status < 0)
4115 break;
4116 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4117 if (status < 0)
4118 break;
4119 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4120 if (status < 0)
4121 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004122 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004123 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 2);
4124 if (status < 0)
4125 break;
4126 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 2);
4127 if (status < 0)
4128 break;
4129 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 2);
4130 if (status < 0)
4131 break;
4132 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 2);
4133 if (status < 0)
4134 break;
4135 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 2);
4136 if (status < 0)
4137 break;
4138 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4139 if (status < 0)
4140 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004141
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004142 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 5);
4143 if (status < 0)
4144 break;
4145 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 4);
4146 if (status < 0)
4147 break;
4148 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4149 if (status < 0)
4150 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004151
Oliver Endrissebc7de22011-07-03 13:49:44 -03004152 /* QAM Slicer Settings */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004153 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4154 if (status < 0)
4155 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004156
Oliver Endrissebc7de22011-07-03 13:49:44 -03004157 /* QAM Loop Controller Coeficients */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004158 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4159 if (status < 0)
4160 break;
4161 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4162 if (status < 0)
4163 break;
4164 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4165 if (status < 0)
4166 break;
4167 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4168 if (status < 0)
4169 break;
4170 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4171 if (status < 0)
4172 break;
4173 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4174 if (status < 0)
4175 break;
4176 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4177 if (status < 0)
4178 break;
4179 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4180 if (status < 0)
4181 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004182
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004183 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4184 if (status < 0)
4185 break;
4186 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4187 if (status < 0)
4188 break;
4189 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4190 if (status < 0)
4191 break;
4192 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4193 if (status < 0)
4194 break;
4195 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4196 if (status < 0)
4197 break;
4198 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4199 if (status < 0)
4200 break;
4201 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4202 if (status < 0)
4203 break;
4204 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4205 if (status < 0)
4206 break;
4207 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4208 if (status < 0)
4209 break;
4210 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4211 if (status < 0)
4212 break;
4213 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4214 if (status < 0)
4215 break;
4216 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4217 if (status < 0)
4218 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004219
4220
Oliver Endrissebc7de22011-07-03 13:49:44 -03004221 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004222
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004223 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4224 if (status < 0)
4225 break;
4226 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4227 if (status < 0)
4228 break;
4229 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4230 if (status < 0)
4231 break;
4232 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4233 if (status < 0)
4234 break;
4235 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4236 if (status < 0)
4237 break;
4238 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4239 if (status < 0)
4240 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004241
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004242 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4243 if (status < 0)
4244 break;
4245 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4246 if (status < 0)
4247 break;
4248 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4249 if (status < 0)
4250 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004251
4252
Oliver Endrissebc7de22011-07-03 13:49:44 -03004253 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004254
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004255 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4256 if (status < 0)
4257 break;
4258 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4259 if (status < 0)
4260 break;
4261 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4262 if (status < 0)
4263 break;
4264 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4265 if (status < 0)
4266 break;
4267 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4268 if (status < 0)
4269 break;
4270 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4271 if (status < 0)
4272 break;
4273 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4274 if (status < 0)
4275 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004276 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004277
Oliver Endrissebc7de22011-07-03 13:49:44 -03004278 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004279}
4280
4281/*============================================================================*/
4282
4283/**
4284* \brief QAM32 specific setup
4285* \param demod instance of demod.
4286* \return DRXStatus_t.
4287*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004288static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004289{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004290 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004291
Oliver Endrissebc7de22011-07-03 13:49:44 -03004292 do {
4293 /* QAM Equalizer Setup */
4294 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004295 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4296 if (status < 0)
4297 break;
4298 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4299 if (status < 0)
4300 break;
4301 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4302 if (status < 0)
4303 break;
4304 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4305 if (status < 0)
4306 break;
4307 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4308 if (status < 0)
4309 break;
4310 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4311 if (status < 0)
4312 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004313
Oliver Endrissebc7de22011-07-03 13:49:44 -03004314 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004315 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 3);
4316 if (status < 0)
4317 break;
4318 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 3);
4319 if (status < 0)
4320 break;
4321 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 3);
4322 if (status < 0)
4323 break;
4324 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 3);
4325 if (status < 0)
4326 break;
4327 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 3);
4328 if (status < 0)
4329 break;
4330 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4331 if (status < 0)
4332 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004333
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004334 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 6);
4335 if (status < 0)
4336 break;
4337 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 5);
4338 if (status < 0)
4339 break;
4340 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4341 if (status < 0)
4342 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004343
Oliver Endrissebc7de22011-07-03 13:49:44 -03004344 /* QAM Slicer Settings */
4345
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004346 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4347 if (status < 0)
4348 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004349
4350
Oliver Endrissebc7de22011-07-03 13:49:44 -03004351 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004352
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004353 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4354 if (status < 0)
4355 break;
4356 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4357 if (status < 0)
4358 break;
4359 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4360 if (status < 0)
4361 break;
4362 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4363 if (status < 0)
4364 break;
4365 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4366 if (status < 0)
4367 break;
4368 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4369 if (status < 0)
4370 break;
4371 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4372 if (status < 0)
4373 break;
4374 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4375 if (status < 0)
4376 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004377
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004378 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4379 if (status < 0)
4380 break;
4381 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4382 if (status < 0)
4383 break;
4384 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4385 if (status < 0)
4386 break;
4387 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4388 if (status < 0)
4389 break;
4390 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4391 if (status < 0)
4392 break;
4393 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4394 if (status < 0)
4395 break;
4396 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4397 if (status < 0)
4398 break;
4399 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4400 if (status < 0)
4401 break;
4402 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4403 if (status < 0)
4404 break;
4405 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4406 if (status < 0)
4407 break;
4408 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4409 if (status < 0)
4410 break;
4411 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4412 if (status < 0)
4413 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004414
4415
Oliver Endrissebc7de22011-07-03 13:49:44 -03004416 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004417
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004418 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4419 if (status < 0)
4420 break;
4421 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4422 if (status < 0)
4423 break;
4424 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4425 if (status < 0)
4426 break;
4427 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4428 if (status < 0)
4429 break;
4430 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4431 if (status < 0)
4432 break;
4433 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4434 if (status < 0)
4435 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004436
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004437 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4438 if (status < 0)
4439 break;
4440 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4441 if (status < 0)
4442 break;
4443 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4444 if (status < 0)
4445 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004446
4447
Oliver Endrissebc7de22011-07-03 13:49:44 -03004448 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004449
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004450 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4451 if (status < 0)
4452 break;
4453 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4454 if (status < 0)
4455 break;
4456 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4457 if (status < 0)
4458 break;
4459 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4460 if (status < 0)
4461 break;
4462 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4463 if (status < 0)
4464 break;
4465 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4466 if (status < 0)
4467 break;
4468 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4469 if (status < 0)
4470 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004471 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004472
Oliver Endrissebc7de22011-07-03 13:49:44 -03004473 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004474}
4475
4476/*============================================================================*/
4477
4478/**
4479* \brief QAM64 specific setup
4480* \param demod instance of demod.
4481* \return DRXStatus_t.
4482*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004483static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004484{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004485 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004486
Oliver Endrissebc7de22011-07-03 13:49:44 -03004487 do {
4488 /* QAM Equalizer Setup */
4489 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004490 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4491 if (status < 0)
4492 break;
4493 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4494 if (status < 0)
4495 break;
4496 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4497 if (status < 0)
4498 break;
4499 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4500 if (status < 0)
4501 break;
4502 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4503 if (status < 0)
4504 break;
4505 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4506 if (status < 0)
4507 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004508
Oliver Endrissebc7de22011-07-03 13:49:44 -03004509 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004510 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 4);
4511 if (status < 0)
4512 break;
4513 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 4);
4514 if (status < 0)
4515 break;
4516 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 4);
4517 if (status < 0)
4518 break;
4519 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 4);
4520 if (status < 0)
4521 break;
4522 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 3);
4523 if (status < 0)
4524 break;
4525 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4526 if (status < 0)
4527 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004528
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004529 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 5);
4530 if (status < 0)
4531 break;
4532 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 4);
4533 if (status < 0)
4534 break;
4535 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4536 if (status < 0)
4537 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004538
4539 /* QAM Slicer Settings */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004540 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4541 if (status < 0)
4542 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004543
4544
Oliver Endrissebc7de22011-07-03 13:49:44 -03004545 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004546
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004547 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4548 if (status < 0)
4549 break;
4550 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4551 if (status < 0)
4552 break;
4553 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4554 if (status < 0)
4555 break;
4556 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4557 if (status < 0)
4558 break;
4559 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4560 if (status < 0)
4561 break;
4562 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4563 if (status < 0)
4564 break;
4565 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4566 if (status < 0)
4567 break;
4568 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4569 if (status < 0)
4570 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004571
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004572 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4573 if (status < 0)
4574 break;
4575 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4576 if (status < 0)
4577 break;
4578 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4579 if (status < 0)
4580 break;
4581 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4582 if (status < 0)
4583 break;
4584 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4585 if (status < 0)
4586 break;
4587 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4588 if (status < 0)
4589 break;
4590 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4591 if (status < 0)
4592 break;
4593 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4594 if (status < 0)
4595 break;
4596 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4597 if (status < 0)
4598 break;
4599 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4600 if (status < 0)
4601 break;
4602 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4603 if (status < 0)
4604 break;
4605 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4606 if (status < 0)
4607 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004608
4609
Oliver Endrissebc7de22011-07-03 13:49:44 -03004610 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004611
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004612 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4613 if (status < 0)
4614 break;
4615 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4616 if (status < 0)
4617 break;
4618 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4619 if (status < 0)
4620 break;
4621 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4622 if (status < 0)
4623 break;
4624 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4625 if (status < 0)
4626 break;
4627 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4628 if (status < 0)
4629 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004630
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004631 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4632 if (status < 0)
4633 break;
4634 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4635 if (status < 0)
4636 break;
4637 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4638 if (status < 0)
4639 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004640
4641
Oliver Endrissebc7de22011-07-03 13:49:44 -03004642 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004643
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004644 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4645 if (status < 0)
4646 break;
4647 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4648 if (status < 0)
4649 break;
4650 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4651 if (status < 0)
4652 break;
4653 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4654 if (status < 0)
4655 break;
4656 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4657 if (status < 0)
4658 break;
4659 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4660 if (status < 0)
4661 break;
4662 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4663 if (status < 0)
4664 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004665 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004666
Oliver Endrissebc7de22011-07-03 13:49:44 -03004667 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004668}
4669
4670/*============================================================================*/
4671
4672/**
4673* \brief QAM128 specific setup
4674* \param demod: instance of demod.
4675* \return DRXStatus_t.
4676*/
4677static int SetQAM128(struct drxk_state *state)
4678{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004679 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004680
Oliver Endrissebc7de22011-07-03 13:49:44 -03004681 do {
4682 /* QAM Equalizer Setup */
4683 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004684 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4685 if (status < 0)
4686 break;
4687 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4688 if (status < 0)
4689 break;
4690 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4691 if (status < 0)
4692 break;
4693 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4694 if (status < 0)
4695 break;
4696 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4697 if (status < 0)
4698 break;
4699 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4700 if (status < 0)
4701 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004702
Oliver Endrissebc7de22011-07-03 13:49:44 -03004703 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004704 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 6);
4705 if (status < 0)
4706 break;
4707 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 6);
4708 if (status < 0)
4709 break;
4710 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 6);
4711 if (status < 0)
4712 break;
4713 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 6);
4714 if (status < 0)
4715 break;
4716 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 5);
4717 if (status < 0)
4718 break;
4719 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4720 if (status < 0)
4721 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004722
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004723 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 6);
4724 if (status < 0)
4725 break;
4726 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 5);
4727 if (status < 0)
4728 break;
4729 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4730 if (status < 0)
4731 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004732
4733
Oliver Endrissebc7de22011-07-03 13:49:44 -03004734 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004735
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004736 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4737 if (status < 0)
4738 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004739
4740
Oliver Endrissebc7de22011-07-03 13:49:44 -03004741 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004742
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004743 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4744 if (status < 0)
4745 break;
4746 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4747 if (status < 0)
4748 break;
4749 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4750 if (status < 0)
4751 break;
4752 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4753 if (status < 0)
4754 break;
4755 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4756 if (status < 0)
4757 break;
4758 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4759 if (status < 0)
4760 break;
4761 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4762 if (status < 0)
4763 break;
4764 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4765 if (status < 0)
4766 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004767
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004768 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4769 if (status < 0)
4770 break;
4771 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4772 if (status < 0)
4773 break;
4774 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4775 if (status < 0)
4776 break;
4777 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4778 if (status < 0)
4779 break;
4780 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4781 if (status < 0)
4782 break;
4783 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4784 if (status < 0)
4785 break;
4786 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4787 if (status < 0)
4788 break;
4789 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4790 if (status < 0)
4791 break;
4792 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4793 if (status < 0)
4794 break;
4795 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4796 if (status < 0)
4797 break;
4798 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4799 if (status < 0)
4800 break;
4801 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4802 if (status < 0)
4803 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004804
4805
Oliver Endrissebc7de22011-07-03 13:49:44 -03004806 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004807
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004808 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4809 if (status < 0)
4810 break;
4811 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4812 if (status < 0)
4813 break;
4814 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4815 if (status < 0)
4816 break;
4817 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4818 if (status < 0)
4819 break;
4820 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4821 if (status < 0)
4822 break;
4823 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4824 if (status < 0)
4825 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004826
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004827 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4828 if (status < 0)
4829 break;
4830 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
4831 if (status < 0)
4832 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004833
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004834 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
4835 if (status < 0)
4836 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004837
Oliver Endrissebc7de22011-07-03 13:49:44 -03004838 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004839
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004840 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
4841 if (status < 0)
4842 break;
4843 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
4844 if (status < 0)
4845 break;
4846 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
4847 if (status < 0)
4848 break;
4849 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
4850 if (status < 0)
4851 break;
4852 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
4853 if (status < 0)
4854 break;
4855 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
4856 if (status < 0)
4857 break;
4858 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
4859 if (status < 0)
4860 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004861 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004862
Oliver Endrissebc7de22011-07-03 13:49:44 -03004863 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004864}
4865
4866/*============================================================================*/
4867
4868/**
4869* \brief QAM256 specific setup
4870* \param demod: instance of demod.
4871* \return DRXStatus_t.
4872*/
4873static int SetQAM256(struct drxk_state *state)
4874{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004875 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004876
Oliver Endrissebc7de22011-07-03 13:49:44 -03004877 do {
4878 /* QAM Equalizer Setup */
4879 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004880 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
4881 if (status < 0)
4882 break;
4883 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
4884 if (status < 0)
4885 break;
4886 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
4887 if (status < 0)
4888 break;
4889 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
4890 if (status < 0)
4891 break;
4892 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
4893 if (status < 0)
4894 break;
4895 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
4896 if (status < 0)
4897 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004898
Oliver Endrissebc7de22011-07-03 13:49:44 -03004899 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004900 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 8);
4901 if (status < 0)
4902 break;
4903 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 8);
4904 if (status < 0)
4905 break;
4906 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 8);
4907 if (status < 0)
4908 break;
4909 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 8);
4910 if (status < 0)
4911 break;
4912 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 6);
4913 if (status < 0)
4914 break;
4915 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4916 if (status < 0)
4917 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004918
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004919 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 5);
4920 if (status < 0)
4921 break;
4922 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 4);
4923 if (status < 0)
4924 break;
4925 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4926 if (status < 0)
4927 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004928
Oliver Endrissebc7de22011-07-03 13:49:44 -03004929 /* QAM Slicer Settings */
4930
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004931 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
4932 if (status < 0)
4933 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004934
4935
Oliver Endrissebc7de22011-07-03 13:49:44 -03004936 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004937
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004938 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4939 if (status < 0)
4940 break;
4941 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4942 if (status < 0)
4943 break;
4944 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4945 if (status < 0)
4946 break;
4947 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4948 if (status < 0)
4949 break;
4950 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4951 if (status < 0)
4952 break;
4953 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4954 if (status < 0)
4955 break;
4956 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4957 if (status < 0)
4958 break;
4959 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4960 if (status < 0)
4961 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004962
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004963 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4964 if (status < 0)
4965 break;
4966 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
4967 if (status < 0)
4968 break;
4969 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
4970 if (status < 0)
4971 break;
4972 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4973 if (status < 0)
4974 break;
4975 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
4976 if (status < 0)
4977 break;
4978 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
4979 if (status < 0)
4980 break;
4981 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4982 if (status < 0)
4983 break;
4984 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4985 if (status < 0)
4986 break;
4987 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4988 if (status < 0)
4989 break;
4990 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4991 if (status < 0)
4992 break;
4993 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4994 if (status < 0)
4995 break;
4996 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4997 if (status < 0)
4998 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004999
5000
Oliver Endrissebc7de22011-07-03 13:49:44 -03005001 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005002
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005003 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5004 if (status < 0)
5005 break;
5006 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5007 if (status < 0)
5008 break;
5009 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5010 if (status < 0)
5011 break;
5012 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5013 if (status < 0)
5014 break;
5015 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5016 if (status < 0)
5017 break;
5018 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5019 if (status < 0)
5020 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005021
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005022 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5023 if (status < 0)
5024 break;
5025 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5026 if (status < 0)
5027 break;
5028 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5029 if (status < 0)
5030 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005031
5032
Oliver Endrissebc7de22011-07-03 13:49:44 -03005033 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005034
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005035 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5036 if (status < 0)
5037 break;
5038 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5039 if (status < 0)
5040 break;
5041 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5042 if (status < 0)
5043 break;
5044 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5045 if (status < 0)
5046 break;
5047 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5048 if (status < 0)
5049 break;
5050 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5051 if (status < 0)
5052 break;
5053 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5054 if (status < 0)
5055 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005056 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005057
Oliver Endrissebc7de22011-07-03 13:49:44 -03005058 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005059}
5060
5061
5062/*============================================================================*/
5063/**
5064* \brief Reset QAM block.
5065* \param demod: instance of demod.
5066* \param channel: pointer to channel data.
5067* \return DRXStatus_t.
5068*/
5069static int QAMResetQAM(struct drxk_state *state)
5070{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005071 int status;
5072 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005073
Oliver Endrissebc7de22011-07-03 13:49:44 -03005074 do {
5075 /* Stop QAM comstate->m_exec */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005076 status = Write16_0(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5077 if (status < 0)
5078 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005079
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005080 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5081 if (status < 0)
5082 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005083 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005084
Oliver Endrissebc7de22011-07-03 13:49:44 -03005085 /* All done, all OK */
5086 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005087}
5088
5089/*============================================================================*/
5090
5091/**
5092* \brief Set QAM symbolrate.
5093* \param demod: instance of demod.
5094* \param channel: pointer to channel data.
5095* \return DRXStatus_t.
5096*/
5097static int QAMSetSymbolrate(struct drxk_state *state)
5098{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005099 u32 adcFrequency = 0;
5100 u32 symbFreq = 0;
5101 u32 iqmRcRate = 0;
5102 u16 ratesel = 0;
5103 u32 lcSymbRate = 0;
5104 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005105
Oliver Endrissebc7de22011-07-03 13:49:44 -03005106 do {
5107 /* Select & calculate correct IQM rate */
5108 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5109 ratesel = 0;
5110 /* printk(KERN_DEBUG "SR %d\n", state->param.u.qam.symbol_rate); */
5111 if (state->param.u.qam.symbol_rate <= 1188750)
5112 ratesel = 3;
5113 else if (state->param.u.qam.symbol_rate <= 2377500)
5114 ratesel = 2;
5115 else if (state->param.u.qam.symbol_rate <= 4755000)
5116 ratesel = 1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005117 status = Write16_0(state, IQM_FD_RATESEL__A, ratesel);
5118 if (status < 0)
5119 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005120
Oliver Endrissebc7de22011-07-03 13:49:44 -03005121 /*
5122 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5123 */
5124 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5125 if (symbFreq == 0) {
5126 /* Divide by zero */
5127 return -1;
5128 }
5129 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5130 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5131 (1 << 23);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005132 status = Write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate, 0);
5133 if (status < 0)
5134 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005135 state->m_iqmRcRate = iqmRcRate;
5136 /*
5137 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5138 */
5139 symbFreq = state->param.u.qam.symbol_rate;
5140 if (adcFrequency == 0) {
5141 /* Divide by zero */
5142 return -1;
5143 }
5144 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5145 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5146 16);
5147 if (lcSymbRate > 511)
5148 lcSymbRate = 511;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005149 status = Write16_0(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
5150 if (status < 0)
5151 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005152 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005153
Oliver Endrissebc7de22011-07-03 13:49:44 -03005154 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005155}
5156
5157/*============================================================================*/
5158
5159/**
5160* \brief Get QAM lock status.
5161* \param demod: instance of demod.
5162* \param channel: pointer to channel data.
5163* \return DRXStatus_t.
5164*/
5165
5166static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5167{
5168 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005169 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005170
Oliver Endrissebc7de22011-07-03 13:49:44 -03005171 status =
5172 scu_command(state,
5173 SCU_RAM_COMMAND_STANDARD_QAM |
5174 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5175 Result);
5176 if (status < 0)
5177 printk(KERN_ERR "%s status = %08x\n", __func__, status);
5178
5179 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005180 /* 0x0000 NOT LOCKED */
5181 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005182 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005183 /* 0x4000 DEMOD LOCKED */
5184 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005185 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005186 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5187 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005188 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005189 /* 0xC000 NEVER LOCKED */
5190 /* (system will never be able to lock to the signal) */
5191 /* TODO: check this, intermediate & standard specific lock states are not
5192 taken into account here */
5193 *pLockStatus = NEVER_LOCK;
5194 }
5195 return status;
5196}
5197
5198#define QAM_MIRROR__M 0x03
5199#define QAM_MIRROR_NORMAL 0x00
5200#define QAM_MIRRORED 0x01
5201#define QAM_MIRROR_AUTO_ON 0x02
5202#define QAM_LOCKRANGE__M 0x10
5203#define QAM_LOCKRANGE_NORMAL 0x10
5204
Oliver Endrissebc7de22011-07-03 13:49:44 -03005205static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5206 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005207{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005208 int status = 0;
5209 u8 parameterLen;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005210 u16 setEnvParameters[5];
5211 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5212 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005213
5214 do {
5215 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005216 STEP 1: reset demodulator
5217 resets FEC DI and FEC RS
5218 resets QAM block
5219 resets SCU variables
5220 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005221 status = Write16_0(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
5222 if (status < 0)
5223 break;
5224 status = Write16_0(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5225 if (status < 0)
5226 break;
5227 status = QAMResetQAM(state);
5228 if (status < 0)
5229 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005230
5231 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005232 STEP 2: configure demodulator
5233 -set env
5234 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5235 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005236 status = QAMSetSymbolrate(state);
5237 if (status < 0)
5238 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005239
5240 /* Env parameters */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005241 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005242 if (state->m_OperationMode == OM_QAM_ITU_C)
Oliver Endrissebc7de22011-07-03 13:49:44 -03005243 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005244 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005245 /* check for LOCKRANGE Extented */
5246 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005247 parameterLen = 4;
5248
5249 /* Set params */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005250 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005251 case QAM_256:
5252 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5253 break;
5254 case QAM_AUTO:
5255 case QAM_64:
5256 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5257 break;
5258 case QAM_16:
5259 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5260 break;
5261 case QAM_32:
5262 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5263 break;
5264 case QAM_128:
5265 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5266 break;
5267 default:
5268 status = -EINVAL;
5269 break;
5270 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005271 status = status;
5272 if (status < 0)
5273 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005274 setParamParameters[0] = state->m_Constellation; /* constellation */
5275 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005276
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005277 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5278 if (status < 0)
5279 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005280
5281
5282 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5283 setup constellation independent registers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005284#if 0
5285 status = SetFrequency (channel, tunerFreqOffset));
5286 if (status < 0)
5287 break;
5288#endif
5289 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5290 if (status < 0)
5291 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005292
5293 /* Setup BER measurement */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005294 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5295 if (status < 0)
5296 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005297
5298 /* Reset default values */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005299 status = Write16_0(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5300 if (status < 0)
5301 break;
5302 status = Write16_0(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5303 if (status < 0)
5304 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005305
Oliver Endrissebc7de22011-07-03 13:49:44 -03005306 /* Reset default LC values */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005307 status = Write16_0(state, QAM_LC_RATE_LIMIT__A, 3);
5308 if (status < 0)
5309 break;
5310 status = Write16_0(state, QAM_LC_LPF_FACTORP__A, 4);
5311 if (status < 0)
5312 break;
5313 status = Write16_0(state, QAM_LC_LPF_FACTORI__A, 4);
5314 if (status < 0)
5315 break;
5316 status = Write16_0(state, QAM_LC_MODE__A, 7);
5317 if (status < 0)
5318 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005319
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005320 status = Write16_0(state, QAM_LC_QUAL_TAB0__A, 1);
5321 if (status < 0)
5322 break;
5323 status = Write16_0(state, QAM_LC_QUAL_TAB1__A, 1);
5324 if (status < 0)
5325 break;
5326 status = Write16_0(state, QAM_LC_QUAL_TAB2__A, 1);
5327 if (status < 0)
5328 break;
5329 status = Write16_0(state, QAM_LC_QUAL_TAB3__A, 1);
5330 if (status < 0)
5331 break;
5332 status = Write16_0(state, QAM_LC_QUAL_TAB4__A, 2);
5333 if (status < 0)
5334 break;
5335 status = Write16_0(state, QAM_LC_QUAL_TAB5__A, 2);
5336 if (status < 0)
5337 break;
5338 status = Write16_0(state, QAM_LC_QUAL_TAB6__A, 2);
5339 if (status < 0)
5340 break;
5341 status = Write16_0(state, QAM_LC_QUAL_TAB8__A, 2);
5342 if (status < 0)
5343 break;
5344 status = Write16_0(state, QAM_LC_QUAL_TAB9__A, 2);
5345 if (status < 0)
5346 break;
5347 status = Write16_0(state, QAM_LC_QUAL_TAB10__A, 2);
5348 if (status < 0)
5349 break;
5350 status = Write16_0(state, QAM_LC_QUAL_TAB12__A, 2);
5351 if (status < 0)
5352 break;
5353 status = Write16_0(state, QAM_LC_QUAL_TAB15__A, 3);
5354 if (status < 0)
5355 break;
5356 status = Write16_0(state, QAM_LC_QUAL_TAB16__A, 3);
5357 if (status < 0)
5358 break;
5359 status = Write16_0(state, QAM_LC_QUAL_TAB20__A, 4);
5360 if (status < 0)
5361 break;
5362 status = Write16_0(state, QAM_LC_QUAL_TAB25__A, 4);
5363 if (status < 0)
5364 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005365
Oliver Endrissebc7de22011-07-03 13:49:44 -03005366 /* Mirroring, QAM-block starting point not inverted */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005367 status = Write16_0(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5368 if (status < 0)
5369 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005370
Oliver Endrissebc7de22011-07-03 13:49:44 -03005371 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005372 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5373 if (status < 0)
5374 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005375
Oliver Endrissebc7de22011-07-03 13:49:44 -03005376 /* STEP 4: constellation specific setup */
5377 switch (state->param.u.qam.modulation) {
5378 case QAM_16:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005379 status = SetQAM16(state);
5380 if (status < 0)
5381 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005382 break;
5383 case QAM_32:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005384 status = SetQAM32(state);
5385 if (status < 0)
5386 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005387 break;
5388 case QAM_AUTO:
5389 case QAM_64:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005390 status = SetQAM64(state);
5391 if (status < 0)
5392 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005393 break;
5394 case QAM_128:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005395 status = SetQAM128(state);
5396 if (status < 0)
5397 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005398 break;
5399 case QAM_256:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005400 status = SetQAM256(state);
5401 if (status < 0)
5402 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005403 break;
5404 default:
5405 return -1;
5406 break;
5407 } /* switch */
5408 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005409 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5410 if (status < 0)
5411 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005412
5413
Oliver Endrissebc7de22011-07-03 13:49:44 -03005414 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5415 /* extAttr->currentChannel.constellation = channel->constellation; */
5416 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005417 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5418 if (status < 0)
5419 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005420
Oliver Endrissebc7de22011-07-03 13:49:44 -03005421 /* Start processes */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005422 status = MPEGTSStart(state);
5423 if (status < 0)
5424 break;
5425 status = Write16_0(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5426 if (status < 0)
5427 break;
5428 status = Write16_0(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5429 if (status < 0)
5430 break;
5431 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5432 if (status < 0)
5433 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005434
Oliver Endrissebc7de22011-07-03 13:49:44 -03005435 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005436 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5437 if (status < 0)
5438 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005439
Oliver Endrissebc7de22011-07-03 13:49:44 -03005440 /* update global DRXK data container */
5441 /*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005442
Oliver Endrissebc7de22011-07-03 13:49:44 -03005443 /* All done, all OK */
5444 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005445
Oliver Endrissebc7de22011-07-03 13:49:44 -03005446 if (status < 0)
5447 printk(KERN_ERR "%s %d\n", __func__, status);
5448
5449 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005450}
5451
Oliver Endrissebc7de22011-07-03 13:49:44 -03005452static int SetQAMStandard(struct drxk_state *state,
5453 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005454{
5455#ifdef DRXK_QAM_TAPS
5456#define DRXK_QAMA_TAPS_SELECT
5457#include "drxk_filters.h"
5458#undef DRXK_QAMA_TAPS_SELECT
5459#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03005460 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005461#endif
5462
Oliver Endrissebc7de22011-07-03 13:49:44 -03005463 do {
5464 /* added antenna switch */
5465 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005466
Oliver Endrissebc7de22011-07-03 13:49:44 -03005467 /* Ensure correct power-up mode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005468 status = PowerUpQAM(state);
5469 if (status < 0)
5470 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005471 /* Reset QAM block */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005472 status = QAMResetQAM(state);
5473 if (status < 0)
5474 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005475
Oliver Endrissebc7de22011-07-03 13:49:44 -03005476 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005477
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005478 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5479 if (status < 0)
5480 break;
5481 status = Write16_0(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5482 if (status < 0)
5483 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005484
Oliver Endrissebc7de22011-07-03 13:49:44 -03005485 /* Upload IQM Channel Filter settings by
5486 boot loader from ROM table */
5487 switch (oMode) {
5488 case OM_QAM_ITU_A:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005489 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5490 if (status < 0)
5491 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005492 break;
5493 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005494 status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5495 if (status < 0)
5496 break;
5497 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5498 if (status < 0)
5499 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005500 break;
5501 default:
5502 status = -EINVAL;
5503 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005504 status = status;
5505 if (status < 0)
5506 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005507
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005508 status = Write16_0(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5509 if (status < 0)
5510 break;
5511 status = Write16_0(state, IQM_CF_SYMMETRIC__A, 0);
5512 if (status < 0)
5513 break;
5514 status = Write16_0(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5515 if (status < 0)
5516 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005517
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005518 status = Write16_0(state, IQM_RC_STRETCH__A, 21);
5519 if (status < 0)
5520 break;
5521 status = Write16_0(state, IQM_AF_CLP_LEN__A, 0);
5522 if (status < 0)
5523 break;
5524 status = Write16_0(state, IQM_AF_CLP_TH__A, 448);
5525 if (status < 0)
5526 break;
5527 status = Write16_0(state, IQM_AF_SNS_LEN__A, 0);
5528 if (status < 0)
5529 break;
5530 status = Write16_0(state, IQM_CF_POW_MEAS_LEN__A, 0);
5531 if (status < 0)
5532 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005533
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005534 status = Write16_0(state, IQM_FS_ADJ_SEL__A, 1);
5535 if (status < 0)
5536 break;
5537 status = Write16_0(state, IQM_RC_ADJ_SEL__A, 1);
5538 if (status < 0)
5539 break;
5540 status = Write16_0(state, IQM_CF_ADJ_SEL__A, 1);
5541 if (status < 0)
5542 break;
5543 status = Write16_0(state, IQM_AF_UPD_SEL__A, 0);
5544 if (status < 0)
5545 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005546
Oliver Endrissebc7de22011-07-03 13:49:44 -03005547 /* IQM Impulse Noise Processing Unit */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005548 status = Write16_0(state, IQM_CF_CLP_VAL__A, 500);
5549 if (status < 0)
5550 break;
5551 status = Write16_0(state, IQM_CF_DATATH__A, 1000);
5552 if (status < 0)
5553 break;
5554 status = Write16_0(state, IQM_CF_BYPASSDET__A, 1);
5555 if (status < 0)
5556 break;
5557 status = Write16_0(state, IQM_CF_DET_LCT__A, 0);
5558 if (status < 0)
5559 break;
5560 status = Write16_0(state, IQM_CF_WND_LEN__A, 1);
5561 if (status < 0)
5562 break;
5563 status = Write16_0(state, IQM_CF_PKDTH__A, 1);
5564 if (status < 0)
5565 break;
5566 status = Write16_0(state, IQM_AF_INC_BYPASS__A, 1);
5567 if (status < 0)
5568 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005569
Oliver Endrissebc7de22011-07-03 13:49:44 -03005570 /* turn on IQMAF. Must be done before setAgc**() */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005571 status = SetIqmAf(state, true);
5572 if (status < 0)
5573 break;
5574 status = Write16_0(state, IQM_AF_START_LOCK__A, 0x01);
5575 if (status < 0)
5576 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005577
Oliver Endrissebc7de22011-07-03 13:49:44 -03005578 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005579 status = ADCSynchronization(state);
5580 if (status < 0)
5581 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005582
Oliver Endrissebc7de22011-07-03 13:49:44 -03005583 /* Set the FSM step period */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005584 status = Write16_0(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5585 if (status < 0)
5586 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005587
Oliver Endrissebc7de22011-07-03 13:49:44 -03005588 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005589 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5590 if (status < 0)
5591 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005592
Oliver Endrissebc7de22011-07-03 13:49:44 -03005593 /* No more resets of the IQM, current standard correctly set =>
5594 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005595
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005596 status = InitAGC(state, true);
5597 if (status < 0)
5598 break;
5599 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5600 if (status < 0)
5601 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005602
Oliver Endrissebc7de22011-07-03 13:49:44 -03005603 /* Configure AGC's */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005604 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5605 if (status < 0)
5606 break;
5607 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5608 if (status < 0)
5609 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005610
Oliver Endrissebc7de22011-07-03 13:49:44 -03005611 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005612 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5613 if (status < 0)
5614 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005615 } while (0);
5616 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005617}
5618
5619static int WriteGPIO(struct drxk_state *state)
5620{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005621 int status;
5622 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005623
Oliver Endrissebc7de22011-07-03 13:49:44 -03005624 do {
5625 /* stop lock indicator process */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005626 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5627 if (status < 0)
5628 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005629
Oliver Endrissebc7de22011-07-03 13:49:44 -03005630 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005631 status = Write16_0(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5632 if (status < 0)
5633 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005634
Oliver Endrissebc7de22011-07-03 13:49:44 -03005635 if (state->m_hasSAWSW) {
5636 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005637 status = Write16_0(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5638 if (status < 0)
5639 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005640
Oliver Endrissebc7de22011-07-03 13:49:44 -03005641 /* use corresponding bit in io data output registar */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005642 status = Read16_0(state, SIO_PDR_UIO_OUT_LO__A, &value);
5643 if (status < 0)
5644 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005645 if (state->m_GPIO == 0)
5646 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5647 else
5648 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5649 /* write back to io data output register */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005650 status = Write16_0(state, SIO_PDR_UIO_OUT_LO__A, value);
5651 if (status < 0)
5652 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005653
Oliver Endrissebc7de22011-07-03 13:49:44 -03005654 }
5655 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005656 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0x0000);
5657 if (status < 0)
5658 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005659 } while (0);
5660 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005661}
5662
5663static int SwitchAntennaToQAM(struct drxk_state *state)
5664{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005665 int status = -1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005666
Oliver Endrissebc7de22011-07-03 13:49:44 -03005667 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5668 if (state->m_GPIO != state->m_AntennaDVBC) {
5669 state->m_GPIO = state->m_AntennaDVBC;
5670 status = WriteGPIO(state);
5671 }
5672 }
5673 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005674}
5675
5676static int SwitchAntennaToDVBT(struct drxk_state *state)
5677{
5678 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005679
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005680 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5681 if (state->m_GPIO != state->m_AntennaDVBT) {
5682 state->m_GPIO = state->m_AntennaDVBT;
5683 status = WriteGPIO(state);
5684 }
5685 }
5686 return status;
5687}
5688
5689
5690static int PowerDownDevice(struct drxk_state *state)
5691{
5692 /* Power down to requested mode */
5693 /* Backup some register settings */
5694 /* Set pins with possible pull-ups connected to them in input mode */
5695 /* Analog power down */
5696 /* ADC power down */
5697 /* Power down device */
5698 int status;
5699 do {
5700 if (state->m_bPDownOpenBridge) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03005701 /* Open I2C bridge before power down of DRXK */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005702 status = ConfigureI2CBridge(state, true);
5703 if (status < 0)
5704 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005705 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005706 /* driver 0.9.0 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005707 status = DVBTEnableOFDMTokenRing(state, false);
5708 if (status < 0)
5709 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005710
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005711 status = Write16_0(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5712 if (status < 0)
5713 break;
5714 status = Write16_0(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5715 if (status < 0)
5716 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005717 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005718 status = HI_CfgCommand(state);
5719 if (status < 0)
5720 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005721 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005722
Oliver Endrissebc7de22011-07-03 13:49:44 -03005723 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005724 return -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005725
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005726 return 0;
5727}
5728
5729static int load_microcode(struct drxk_state *state, char *mc_name)
5730{
5731 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005732 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005733
5734 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5735 if (err < 0) {
5736 printk(KERN_ERR
Oliver Endrissebc7de22011-07-03 13:49:44 -03005737 "Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005738 printk(KERN_INFO
Oliver Endrissebc7de22011-07-03 13:49:44 -03005739 "Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005740 return err;
5741 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005742 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005743 release_firmware(fw);
5744 return err;
5745}
5746
5747static int init_drxk(struct drxk_state *state)
5748{
5749 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005750 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005751 u16 driverVersion;
5752
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005753 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
5754 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005755 status = PowerUpDevice(state);
5756 if (status < 0)
5757 break;
5758 status = DRXX_Open(state);
5759 if (status < 0)
5760 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005761 /* Soft reset of OFDM-, sys- and osc-clockdomain */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005762 status = Write16_0(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
5763 if (status < 0)
5764 break;
5765 status = Write16_0(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5766 if (status < 0)
5767 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005768 /* TODO is this needed, if yes how much delay in worst case scenario */
5769 msleep(1);
5770 state->m_DRXK_A3_PATCH_CODE = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005771 status = GetDeviceCapabilities(state);
5772 if (status < 0)
5773 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005774
5775 /* Bridge delay, uses oscilator clock */
5776 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5777 /* SDA brdige delay */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005778 state->m_HICfgBridgeDelay =
5779 (u16) ((state->m_oscClockFreq / 1000) *
5780 HI_I2C_BRIDGE_DELAY) / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005781 /* Clipping */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005782 if (state->m_HICfgBridgeDelay >
5783 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
5784 state->m_HICfgBridgeDelay =
5785 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005786 }
5787 /* SCL bridge delay, same as SDA for now */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005788 state->m_HICfgBridgeDelay +=
5789 state->m_HICfgBridgeDelay <<
5790 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005791
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005792 status = InitHI(state);
5793 if (status < 0)
5794 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005795 /* disable various processes */
5796#if NOA1ROM
Oliver Endrissebc7de22011-07-03 13:49:44 -03005797 if (!(state->m_DRXK_A1_ROM_CODE)
5798 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005799#endif
5800 {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005801 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5802 if (status < 0)
5803 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005804 }
5805
5806 /* disable MPEG port */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005807 status = MPEGTSDisable(state);
5808 if (status < 0)
5809 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005810
5811 /* Stop AUD and SCU */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005812 status = Write16_0(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
5813 if (status < 0)
5814 break;
5815 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
5816 if (status < 0)
5817 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005818
5819 /* enable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005820 status = Write16_0(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
5821 if (status < 0)
5822 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005823
5824 /* include boot loader section */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005825 status = Write16_0(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
5826 if (status < 0)
5827 break;
5828 status = BLChainCmd(state, 0, 6, 100);
5829 if (status < 0)
5830 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005831
5832#if 0
5833 if (state->m_DRXK_A3_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005834 status = DownloadMicrocode(state, DRXK_A3_microcode, DRXK_A3_microcode_length);
5835 if (status < 0)
5836 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005837#else
5838 load_microcode(state, "drxk_a3.mc");
5839#endif
5840#if NOA1ROM
5841 if (state->m_DRXK_A2_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005842 status = DownloadMicrocode(state, DRXK_A2_microcode, DRXK_A2_microcode_length);
5843 if (status < 0)
5844 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005845#endif
5846 /* disable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005847 status = Write16_0(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
5848 if (status < 0)
5849 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005850
5851 /* Run SCU for a little while to initialize microcode version numbers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005852 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5853 if (status < 0)
5854 break;
5855 status = DRXX_Open(state);
5856 if (status < 0)
5857 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005858 /* added for test */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005859 msleep(30);
5860
5861 powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005862 status = CtrlPowerMode(state, &powerMode);
5863 if (status < 0)
5864 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005865
5866 /* Stamp driver version number in SCU data RAM in BCD code
5867 Done to enable field application engineers to retreive drxdriver version
5868 via I2C from SCU RAM.
5869 Not using SCU command interface for SCU register access since no
5870 microcode may be present.
Oliver Endrissebc7de22011-07-03 13:49:44 -03005871 */
5872 driverVersion =
5873 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
5874 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
5875 ((DRXK_VERSION_MAJOR % 10) << 4) +
5876 (DRXK_VERSION_MINOR % 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005877 status = Write16_0(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
5878 if (status < 0)
5879 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005880 driverVersion =
5881 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
5882 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
5883 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
5884 (DRXK_VERSION_PATCH % 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005885 status = Write16_0(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
5886 if (status < 0)
5887 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005888
Oliver Endrissebc7de22011-07-03 13:49:44 -03005889 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
5890 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
5891 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005892
5893 /* Dirty fix of default values for ROM/PATCH microcode
5894 Dirty because this fix makes it impossible to setup suitable values
5895 before calling DRX_Open. This solution requires changes to RF AGC speed
5896 to be done via the CTRL function after calling DRX_Open */
5897
Oliver Endrissebc7de22011-07-03 13:49:44 -03005898 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005899
5900 /* Reset driver debug flags to 0 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005901 status = Write16_0(state, SCU_RAM_DRIVER_DEBUG__A, 0);
5902 if (status < 0)
5903 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005904 /* driver 0.9.0 */
5905 /* Setup FEC OC:
5906 NOTE: No more full FEC resets allowed afterwards!! */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005907 status = Write16_0(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
5908 if (status < 0)
5909 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005910 /* MPEGTS functions are still the same */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005911 status = MPEGTSDtoInit(state);
5912 if (status < 0)
5913 break;
5914 status = MPEGTSStop(state);
5915 if (status < 0)
5916 break;
5917 status = MPEGTSConfigurePolarity(state);
5918 if (status < 0)
5919 break;
5920 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
5921 if (status < 0)
5922 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005923 /* added: configure GPIO */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005924 status = WriteGPIO(state);
5925 if (status < 0)
5926 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005927
Oliver Endrissebc7de22011-07-03 13:49:44 -03005928 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005929
5930 if (state->m_bPowerDown) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005931 status = PowerDownDevice(state);
5932 if (status < 0)
5933 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005934 state->m_DrxkState = DRXK_POWERED_DOWN;
5935 } else
5936 state->m_DrxkState = DRXK_STOPPED;
5937 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005938 }
5939
5940 return 0;
5941}
5942
Oliver Endrissebc7de22011-07-03 13:49:44 -03005943static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005944{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005945 struct drxk_state *state = fe->demodulator_priv;
5946
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005947 kfree(state);
5948}
5949
Oliver Endrissebc7de22011-07-03 13:49:44 -03005950static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005951{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005952 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005953
Oliver Endrissebc7de22011-07-03 13:49:44 -03005954 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005955 return -EBUSY;
5956 SetOperationMode(state, OM_QAM_ITU_A);
5957 return 0;
5958}
5959
Oliver Endrissebc7de22011-07-03 13:49:44 -03005960static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005961{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005962 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005963
5964 ShutDown(state);
5965 mutex_unlock(&state->ctlock);
5966 return 0;
5967}
5968
Oliver Endrissebc7de22011-07-03 13:49:44 -03005969static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005970{
5971 struct drxk_state *state = fe->demodulator_priv;
5972
Oliver Endrissebc7de22011-07-03 13:49:44 -03005973 /* printk(KERN_DEBUG "drxk_gate %d\n", enable); */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005974 return ConfigureI2CBridge(state, enable ? true : false);
5975}
5976
Oliver Endrissebc7de22011-07-03 13:49:44 -03005977static int drxk_set_parameters(struct dvb_frontend *fe,
5978 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005979{
5980 struct drxk_state *state = fe->demodulator_priv;
5981 u32 IF;
5982
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005983 if (fe->ops.i2c_gate_ctrl)
5984 fe->ops.i2c_gate_ctrl(fe, 1);
5985 if (fe->ops.tuner_ops.set_params)
5986 fe->ops.tuner_ops.set_params(fe, p);
5987 if (fe->ops.i2c_gate_ctrl)
5988 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005989 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005990 fe->ops.tuner_ops.get_frequency(fe, &IF);
5991 Start(state, 0, IF);
5992
Oliver Endrissebc7de22011-07-03 13:49:44 -03005993 /* printk(KERN_DEBUG "%s IF=%d done\n", __func__, IF); */
5994
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005995 return 0;
5996}
5997
Oliver Endrissebc7de22011-07-03 13:49:44 -03005998static int drxk_c_get_frontend(struct dvb_frontend *fe,
5999 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006000{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006001 return 0;
6002}
6003
6004static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6005{
6006 struct drxk_state *state = fe->demodulator_priv;
6007 u32 stat;
6008
Oliver Endrissebc7de22011-07-03 13:49:44 -03006009 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006010 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006011 if (stat == MPEG_LOCK)
6012 *status |= 0x1f;
6013 if (stat == FEC_LOCK)
6014 *status |= 0x0f;
6015 if (stat == DEMOD_LOCK)
6016 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006017 return 0;
6018}
6019
6020static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6021{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006022 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006023 return 0;
6024}
6025
Oliver Endrissebc7de22011-07-03 13:49:44 -03006026static int drxk_read_signal_strength(struct dvb_frontend *fe,
6027 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006028{
6029 struct drxk_state *state = fe->demodulator_priv;
6030 u32 val;
6031
6032 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006033 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006034 return 0;
6035}
6036
6037static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6038{
6039 struct drxk_state *state = fe->demodulator_priv;
6040 s32 snr2;
6041
6042 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006043 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006044 return 0;
6045}
6046
6047static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6048{
6049 struct drxk_state *state = fe->demodulator_priv;
6050 u16 err;
6051
6052 DVBTQAMGetAccPktErr(state, &err);
6053 *ucblocks = (u32) err;
6054 return 0;
6055}
6056
Oliver Endrissebc7de22011-07-03 13:49:44 -03006057static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6058 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006059{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006060 sets->min_delay_ms = 3000;
6061 sets->max_drift = 0;
6062 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006063 return 0;
6064}
6065
Oliver Endrissebc7de22011-07-03 13:49:44 -03006066static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006067{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006068#if 0
6069 struct drxk_state *state = fe->demodulator_priv;
6070
6071 printk(KERN_DEBUG "%s\n", __func__);
6072 kfree(state);
6073#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006074}
6075
Oliver Endrissebc7de22011-07-03 13:49:44 -03006076static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006077{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006078 struct drxk_state *state = fe->demodulator_priv;
6079 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006080 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006081 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006082 return 0;
6083}
6084
Oliver Endrissebc7de22011-07-03 13:49:44 -03006085static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006086{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006087 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006088 mutex_unlock(&state->ctlock);
6089 return 0;
6090}
6091
Oliver Endrissebc7de22011-07-03 13:49:44 -03006092static int drxk_t_get_frontend(struct dvb_frontend *fe,
6093 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006094{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006095 return 0;
6096}
6097
6098static struct dvb_frontend_ops drxk_c_ops = {
6099 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006100 .name = "DRXK DVB-C",
6101 .type = FE_QAM,
6102 .frequency_stepsize = 62500,
6103 .frequency_min = 47000000,
6104 .frequency_max = 862000000,
6105 .symbol_rate_min = 870000,
6106 .symbol_rate_max = 11700000,
6107 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6108 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006109 .release = drxk_c_release,
6110 .init = drxk_c_init,
6111 .sleep = drxk_c_sleep,
6112 .i2c_gate_ctrl = drxk_gate_ctrl,
6113
6114 .set_frontend = drxk_set_parameters,
6115 .get_frontend = drxk_c_get_frontend,
6116 .get_tune_settings = drxk_c_get_tune_settings,
6117
6118 .read_status = drxk_read_status,
6119 .read_ber = drxk_read_ber,
6120 .read_signal_strength = drxk_read_signal_strength,
6121 .read_snr = drxk_read_snr,
6122 .read_ucblocks = drxk_read_ucblocks,
6123};
6124
6125static struct dvb_frontend_ops drxk_t_ops = {
6126 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006127 .name = "DRXK DVB-T",
6128 .type = FE_OFDM,
6129 .frequency_min = 47125000,
6130 .frequency_max = 865000000,
6131 .frequency_stepsize = 166667,
6132 .frequency_tolerance = 0,
6133 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6134 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6135 FE_CAN_FEC_AUTO |
6136 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6137 FE_CAN_QAM_AUTO |
6138 FE_CAN_TRANSMISSION_MODE_AUTO |
6139 FE_CAN_GUARD_INTERVAL_AUTO |
6140 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006141 .release = drxk_t_release,
6142 .init = drxk_t_init,
6143 .sleep = drxk_t_sleep,
6144 .i2c_gate_ctrl = drxk_gate_ctrl,
6145
6146 .set_frontend = drxk_set_parameters,
6147 .get_frontend = drxk_t_get_frontend,
6148
6149 .read_status = drxk_read_status,
6150 .read_ber = drxk_read_ber,
6151 .read_signal_strength = drxk_read_signal_strength,
6152 .read_snr = drxk_read_snr,
6153 .read_ucblocks = drxk_read_ucblocks,
6154};
6155
6156struct dvb_frontend *drxk_attach(struct i2c_adapter *i2c, u8 adr,
6157 struct dvb_frontend **fe_t)
6158{
6159 struct drxk_state *state = NULL;
6160
Oliver Endrissebc7de22011-07-03 13:49:44 -03006161 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006162 if (!state)
6163 return NULL;
6164
Oliver Endrissebc7de22011-07-03 13:49:44 -03006165 state->i2c = i2c;
6166 state->demod_address = adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006167
6168 mutex_init(&state->mutex);
6169 mutex_init(&state->ctlock);
6170
Oliver Endrissebc7de22011-07-03 13:49:44 -03006171 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6172 sizeof(struct dvb_frontend_ops));
6173 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6174 sizeof(struct dvb_frontend_ops));
6175 state->c_frontend.demodulator_priv = state;
6176 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006177
6178 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006179 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006180 goto error;
6181 *fe_t = &state->t_frontend;
6182 return &state->c_frontend;
6183
6184error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006185 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006186 kfree(state);
6187 return NULL;
6188}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006189EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006190
6191MODULE_DESCRIPTION("DRX-K driver");
6192MODULE_AUTHOR("Ralph Metzler");
6193MODULE_LICENSE("GPL");