blob: f550332d7f323176848e407469aaf38a81f5cdd8 [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) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300320 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
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) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300335 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
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) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300482 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
483 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300484 break;
485 }
486 pBlock += Chunk;
487 Address += (Chunk >> 1);
488 BlkSize -= Chunk;
489 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300490 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300491}
492
493#ifndef DRXK_MAX_RETRIES_POWERUP
494#define DRXK_MAX_RETRIES_POWERUP 20
495#endif
496
497int PowerUpDevice(struct drxk_state *state)
498{
499 int status;
500 u8 data = 0;
501 u16 retryCount = 0;
502
503 status = i2c_read1(state->i2c, state->demod_address, &data);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300504 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300505 do {
506 data = 0;
507 if (i2c_write(state->i2c,
508 state->demod_address, &data, 1) < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300509 printk(KERN_ERR "drxk: powerup failed\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300510 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300511 retryCount++;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300512 } while (i2c_read1(state->i2c,
513 state->demod_address, &data) < 0 &&
514 (retryCount < DRXK_MAX_RETRIES_POWERUP));
515 if (retryCount >= DRXK_MAX_RETRIES_POWERUP)
516 return -1;
517 do {
518 /* Make sure all clk domains are active */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300519 status = Write16_0(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
520 if (status < 0)
521 break;
522 status = Write16_0(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
523 if (status < 0)
524 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300525 /* Enable pll lock tests */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300526 status = Write16_0(state, SIO_CC_PLL_LOCK__A, 1);
527 if (status < 0)
528 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300529 state->m_currentPowerMode = DRX_POWER_UP;
530 } while (0);
531 return status;
532}
533
534
535static int init_state(struct drxk_state *state)
536{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300537 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
538 u32 ulVSBIfAgcOutputLevel = 0;
539 u32 ulVSBIfAgcMinLevel = 0;
540 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
541 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300542
Oliver Endrissebc7de22011-07-03 13:49:44 -0300543 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
544 u32 ulVSBRfAgcOutputLevel = 0;
545 u32 ulVSBRfAgcMinLevel = 0;
546 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
547 u32 ulVSBRfAgcSpeed = 3;
548 u32 ulVSBRfAgcTop = 9500;
549 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300550
Oliver Endrissebc7de22011-07-03 13:49:44 -0300551 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
552 u32 ulATVIfAgcOutputLevel = 0;
553 u32 ulATVIfAgcMinLevel = 0;
554 u32 ulATVIfAgcMaxLevel = 0;
555 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300556
Oliver Endrissebc7de22011-07-03 13:49:44 -0300557 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
558 u32 ulATVRfAgcOutputLevel = 0;
559 u32 ulATVRfAgcMinLevel = 0;
560 u32 ulATVRfAgcMaxLevel = 0;
561 u32 ulATVRfAgcTop = 9500;
562 u32 ulATVRfAgcCutOffCurrent = 4000;
563 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300564
565 u32 ulQual83 = DEFAULT_MER_83;
566 u32 ulQual93 = DEFAULT_MER_93;
567
568 u32 ulDVBTStaticTSClock = 1;
569 u32 ulDVBCStaticTSClock = 1;
570
571 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
572 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
573
574 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
575 /* io_pad_cfg_mode output mode is drive always */
576 /* io_pad_cfg_drive is set to power 2 (23 mA) */
577 u32 ulGPIOCfg = 0x0113;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300578 u32 ulGPIO = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300579 u32 ulSerialMode = 1;
580 u32 ulInvertTSClock = 0;
581 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
582 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
583 u32 ulDVBTBitrate = 50000000;
584 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
585
586 u32 ulInsertRSByte = 0;
587
588 u32 ulRfMirror = 1;
589 u32 ulPowerDown = 0;
590
591 u32 ulAntennaDVBT = 1;
592 u32 ulAntennaDVBC = 0;
593 u32 ulAntennaSwitchDVBTDVBC = 0;
594
595 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300596 state->m_hasDVBT = false;
597 state->m_hasDVBC = false;
598 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300599 state->m_hasOOB = false;
600 state->m_hasAudio = false;
601
602 state->m_ChunkSize = 124;
603
604 state->m_oscClockFreq = 0;
605 state->m_smartAntInverted = false;
606 state->m_bPDownOpenBridge = false;
607
608 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300609 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300610 /* Timing div, 250ns/Psys */
611 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
612 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
613 HI_I2C_DELAY) / 1000;
614 /* Clipping */
615 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
616 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
617 state->m_HICfgWakeUpKey = (state->demod_address << 1);
618 /* port/bridge/power down ctrl */
619 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
620
621 state->m_bPowerDown = (ulPowerDown != 0);
622
623 state->m_DRXK_A1_PATCH_CODE = false;
624 state->m_DRXK_A1_ROM_CODE = false;
625 state->m_DRXK_A2_ROM_CODE = false;
626 state->m_DRXK_A3_ROM_CODE = false;
627 state->m_DRXK_A2_PATCH_CODE = false;
628 state->m_DRXK_A3_PATCH_CODE = false;
629
630 /* Init AGC and PGA parameters */
631 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300632 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
633 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
634 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
635 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
636 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300637 state->m_vsbPgaCfg = 140;
638
639 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300640 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
641 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
642 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
643 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
644 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
645 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
646 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
647 state->m_vsbPreSawCfg.reference = 0x07;
648 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300649
650 state->m_Quality83percent = DEFAULT_MER_83;
651 state->m_Quality93percent = DEFAULT_MER_93;
652 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
653 state->m_Quality83percent = ulQual83;
654 state->m_Quality93percent = ulQual93;
655 }
656
657 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300658 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
659 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
660 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
661 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
662 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300663
664 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300665 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
666 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
667 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
668 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
669 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
670 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
671 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
672 state->m_atvPreSawCfg.reference = 0x04;
673 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300674
675
676 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300677 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
678 state->m_dvbtRfAgcCfg.outputLevel = 0;
679 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
680 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
681 state->m_dvbtRfAgcCfg.top = 0x2100;
682 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
683 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300684
685
686 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300687 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
688 state->m_dvbtIfAgcCfg.outputLevel = 0;
689 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
690 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
691 state->m_dvbtIfAgcCfg.top = 13424;
692 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
693 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300694 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300695 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
696 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300697
Oliver Endrissebc7de22011-07-03 13:49:44 -0300698 state->m_dvbtPreSawCfg.reference = 4;
699 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300700
701 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300702 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
703 state->m_qamRfAgcCfg.outputLevel = 0;
704 state->m_qamRfAgcCfg.minOutputLevel = 6023;
705 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
706 state->m_qamRfAgcCfg.top = 0x2380;
707 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
708 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300709
710 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300711 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
712 state->m_qamIfAgcCfg.outputLevel = 0;
713 state->m_qamIfAgcCfg.minOutputLevel = 0;
714 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
715 state->m_qamIfAgcCfg.top = 0x0511;
716 state->m_qamIfAgcCfg.cutOffCurrent = 0;
717 state->m_qamIfAgcCfg.speed = 3;
718 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300719 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
720
Oliver Endrissebc7de22011-07-03 13:49:44 -0300721 state->m_qamPgaCfg = 140;
722 state->m_qamPreSawCfg.reference = 4;
723 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300724
725 state->m_OperationMode = OM_NONE;
726 state->m_DrxkState = DRXK_UNINITIALIZED;
727
728 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300729 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
730 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
731 state->m_enableParallel = true; /* If TRUE;
732 parallel out otherwise serial */
733 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
734 state->m_invertERR = false; /* If TRUE; invert ERR signal */
735 state->m_invertSTR = false; /* If TRUE; invert STR signals */
736 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
737 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300738 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300739 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300740 /* If TRUE; static MPEG clockrate will be used;
741 otherwise clockrate will adapt to the bitrate of the TS */
742
743 state->m_DVBTBitrate = ulDVBTBitrate;
744 state->m_DVBCBitrate = ulDVBCBitrate;
745
746 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
747 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
748
749 /* Maximum bitrate in b/s in case static clockrate is selected */
750 state->m_mpegTsStaticBitrate = 19392658;
751 state->m_disableTEIhandling = false;
752
753 if (ulInsertRSByte)
754 state->m_insertRSByte = true;
755
756 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
757 if (ulMpegLockTimeOut < 10000)
758 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
759 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
760 if (ulDemodLockTimeOut < 10000)
761 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
762
Oliver Endrissebc7de22011-07-03 13:49:44 -0300763 /* QAM defaults */
764 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300765 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300766 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
767 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300768
769 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
770 state->m_agcFastClipCtrlDelay = 0;
771
772 state->m_GPIOCfg = (ulGPIOCfg);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300773 state->m_GPIO = (ulGPIO == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300774
775 state->m_AntennaDVBT = (ulAntennaDVBT == 0 ? 0 : 1);
776 state->m_AntennaDVBC = (ulAntennaDVBC == 0 ? 0 : 1);
777 state->m_AntennaSwitchDVBTDVBC =
Oliver Endrissebc7de22011-07-03 13:49:44 -0300778 (ulAntennaSwitchDVBTDVBC == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300779
780 state->m_bPowerDown = false;
781 state->m_currentPowerMode = DRX_POWER_DOWN;
782
783 state->m_enableParallel = (ulSerialMode == 0);
784
785 state->m_rfmirror = (ulRfMirror == 0);
786 state->m_IfAgcPol = false;
787 return 0;
788}
789
790static int DRXX_Open(struct drxk_state *state)
791{
792 int status = 0;
793 u32 jtag = 0;
794 u16 bid = 0;
795 u16 key = 0;
796
797 do {
798 /* stop lock indicator process */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300799 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
800 if (status < 0)
801 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300802 /* Check device id */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300803 status = Read16(state, SIO_TOP_COMM_KEY__A, &key, 0);
804 if (status < 0)
805 break;
806 status = Write16_0(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
807 if (status < 0)
808 break;
809 status = Read32(state, SIO_TOP_JTAGID_LO__A, &jtag, 0);
810 if (status < 0)
811 break;
812 status = Read16(state, SIO_PDR_UIO_IN_HI__A, &bid, 0);
813 if (status < 0)
814 break;
815 status = Write16_0(state, SIO_TOP_COMM_KEY__A, key);
816 if (status < 0)
817 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300818 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300819 return status;
820}
821
822static int GetDeviceCapabilities(struct drxk_state *state)
823{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300824 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300825 u32 sioTopJtagidLo = 0;
826 int status;
827
828 do {
829 /* driver 0.9.0 */
830 /* stop lock indicator process */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300831 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
832 if (status < 0)
833 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300834
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300835 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0xFABA);
836 if (status < 0)
837 break;
838 status = Read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg, 0);
839 if (status < 0)
840 break;
841 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0x0000);
842 if (status < 0)
843 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300844
845 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
846 case 0:
847 /* ignore (bypass ?) */
848 break;
849 case 1:
850 /* 27 MHz */
851 state->m_oscClockFreq = 27000;
852 break;
853 case 2:
854 /* 20.25 MHz */
855 state->m_oscClockFreq = 20250;
856 break;
857 case 3:
858 /* 4 MHz */
859 state->m_oscClockFreq = 20250;
860 break;
861 default:
862 return -1;
863 }
864 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300865 Determine device capabilities
866 Based on pinning v14
867 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300868 status = Read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo, 0);
869 if (status < 0)
870 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300871 /* driver 0.9.0 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300872 switch ((sioTopJtagidLo >> 29) & 0xF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300873 case 0:
874 state->m_deviceSpin = DRXK_SPIN_A1;
875 break;
876 case 2:
877 state->m_deviceSpin = DRXK_SPIN_A2;
878 break;
879 case 3:
880 state->m_deviceSpin = DRXK_SPIN_A3;
881 break;
882 default:
883 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
884 status = -1;
885 break;
886 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300887 switch ((sioTopJtagidLo >> 12) & 0xFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300888 case 0x13:
889 /* typeId = DRX3913K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300890 state->m_hasLNA = false;
891 state->m_hasOOB = false;
892 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300893 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300894 state->m_hasDVBT = true;
895 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300896 state->m_hasSAWSW = true;
897 state->m_hasGPIO2 = false;
898 state->m_hasGPIO1 = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300899 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300900 break;
901 case 0x15:
902 /* typeId = DRX3915K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300903 state->m_hasLNA = false;
904 state->m_hasOOB = false;
905 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300906 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300907 state->m_hasDVBT = true;
908 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300909 state->m_hasSAWSW = true;
910 state->m_hasGPIO2 = true;
911 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300912 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300913 break;
914 case 0x16:
915 /* typeId = DRX3916K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300916 state->m_hasLNA = false;
917 state->m_hasOOB = false;
918 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300919 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300920 state->m_hasDVBT = true;
921 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300922 state->m_hasSAWSW = true;
923 state->m_hasGPIO2 = true;
924 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300925 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300926 break;
927 case 0x18:
928 /* typeId = DRX3918K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300929 state->m_hasLNA = false;
930 state->m_hasOOB = false;
931 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300932 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300933 state->m_hasDVBT = true;
934 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300935 state->m_hasSAWSW = true;
936 state->m_hasGPIO2 = true;
937 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300938 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300939 break;
940 case 0x21:
941 /* typeId = DRX3921K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300942 state->m_hasLNA = false;
943 state->m_hasOOB = false;
944 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300945 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300946 state->m_hasDVBT = true;
947 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300948 state->m_hasSAWSW = true;
949 state->m_hasGPIO2 = true;
950 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300951 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300952 break;
953 case 0x23:
954 /* typeId = DRX3923K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300955 state->m_hasLNA = false;
956 state->m_hasOOB = false;
957 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300958 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300959 state->m_hasDVBT = true;
960 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300961 state->m_hasSAWSW = true;
962 state->m_hasGPIO2 = true;
963 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300964 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300965 break;
966 case 0x25:
967 /* typeId = DRX3925K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300968 state->m_hasLNA = false;
969 state->m_hasOOB = false;
970 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300971 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300972 state->m_hasDVBT = true;
973 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300974 state->m_hasSAWSW = true;
975 state->m_hasGPIO2 = true;
976 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300977 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300978 break;
979 case 0x26:
980 /* typeId = DRX3926K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300981 state->m_hasLNA = false;
982 state->m_hasOOB = false;
983 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300984 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300985 state->m_hasDVBT = true;
986 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300987 state->m_hasSAWSW = true;
988 state->m_hasGPIO2 = true;
989 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300990 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300991 break;
992 default:
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300993 printk(KERN_ERR "drxk: DeviceID not supported = %02x\n",
Oliver Endrissebc7de22011-07-03 13:49:44 -0300994 ((sioTopJtagidLo >> 12) & 0xFF));
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300995 status = -1;
996 break;
997 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300998 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300999 return status;
1000}
1001
1002static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1003{
1004 int status;
1005 bool powerdown_cmd;
1006
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001007 /* Write command */
1008 status = Write16_0(state, SIO_HI_RA_RAM_CMD__A, cmd);
1009 if (status < 0)
1010 return status;
1011 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1012 msleep(1);
1013
1014 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001015 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1016 ((state->m_HICfgCtrl) &
1017 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1018 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001019 if (powerdown_cmd == false) {
1020 /* Wait until command rdy */
1021 u32 retryCount = 0;
1022 u16 waitCmd;
1023
1024 do {
1025 msleep(1);
1026 retryCount += 1;
1027 status = Read16(state, SIO_HI_RA_RAM_CMD__A,
1028 &waitCmd, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001029 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1030 && (waitCmd != 0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001031
1032 if (status == 0)
1033 status = Read16(state, SIO_HI_RA_RAM_RES__A,
1034 pResult, 0);
1035 }
1036 return status;
1037}
1038
1039static int HI_CfgCommand(struct drxk_state *state)
1040{
1041 int status;
1042
1043 mutex_lock(&state->mutex);
1044 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001045 status = Write16_0(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1046 if (status < 0)
1047 break;
1048 status = Write16_0(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1049 if (status < 0)
1050 break;
1051 status = Write16_0(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1052 if (status < 0)
1053 break;
1054 status = Write16_0(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1055 if (status < 0)
1056 break;
1057 status = Write16_0(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1058 if (status < 0)
1059 break;
1060 status = Write16_0(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1061 if (status < 0)
1062 break;
1063 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1064 if (status < 0)
1065 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001066
1067 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001068 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001069 mutex_unlock(&state->mutex);
1070 return status;
1071}
1072
1073static int InitHI(struct drxk_state *state)
1074{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001075 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001076 state->m_HICfgTimeout = 0x96FF;
1077 /* port/bridge/power down ctrl */
1078 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001079 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001080}
1081
1082static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1083{
1084 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001085 u16 sioPdrMclkCfg = 0;
1086 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001087
1088 do {
1089 /* stop lock indicator process */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001090 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1091 if (status < 0)
1092 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001093
1094 /* MPEG TS pad configuration */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001095 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1096 if (status < 0)
1097 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001098
1099 if (mpegEnable == false) {
1100 /* Set MPEG TS pads to inputmode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001101 status = Write16_0(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1102 if (status < 0)
1103 break;
1104 status = Write16_0(state, SIO_PDR_MERR_CFG__A, 0x0000);
1105 if (status < 0)
1106 break;
1107 status = Write16_0(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1108 if (status < 0)
1109 break;
1110 status = Write16_0(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1111 if (status < 0)
1112 break;
1113 status = Write16_0(state, SIO_PDR_MD0_CFG__A, 0x0000);
1114 if (status < 0)
1115 break;
1116 status = Write16_0(state, SIO_PDR_MD1_CFG__A, 0x0000);
1117 if (status < 0)
1118 break;
1119 status = Write16_0(state, SIO_PDR_MD2_CFG__A, 0x0000);
1120 if (status < 0)
1121 break;
1122 status = Write16_0(state, SIO_PDR_MD3_CFG__A, 0x0000);
1123 if (status < 0)
1124 break;
1125 status = Write16_0(state, SIO_PDR_MD4_CFG__A, 0x0000);
1126 if (status < 0)
1127 break;
1128 status = Write16_0(state, SIO_PDR_MD5_CFG__A, 0x0000);
1129 if (status < 0)
1130 break;
1131 status = Write16_0(state, SIO_PDR_MD6_CFG__A, 0x0000);
1132 if (status < 0)
1133 break;
1134 status = Write16_0(state, SIO_PDR_MD7_CFG__A, 0x0000);
1135 if (status < 0)
1136 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001137 } else {
1138 /* Enable MPEG output */
1139 sioPdrMdxCfg =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001140 ((state->m_TSDataStrength <<
1141 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001142 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03001143 SIO_PDR_MCLK_CFG_DRIVE__B) |
1144 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001145
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001146 status = Write16_0(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1147 if (status < 0)
1148 break;
1149 status = Write16_0(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
1150 if (status < 0)
1151 break;
1152 status = Write16_0(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
1153 if (status < 0)
1154 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001155 if (state->m_enableParallel == true) {
1156 /* paralel -> enable MD1 to MD7 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001157 status = Write16_0(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
1158 if (status < 0)
1159 break;
1160 status = Write16_0(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
1161 if (status < 0)
1162 break;
1163 status = Write16_0(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
1164 if (status < 0)
1165 break;
1166 status = Write16_0(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
1167 if (status < 0)
1168 break;
1169 status = Write16_0(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
1170 if (status < 0)
1171 break;
1172 status = Write16_0(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1173 if (status < 0)
1174 break;
1175 status = Write16_0(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1176 if (status < 0)
1177 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001178 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001179 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1180 SIO_PDR_MD0_CFG_DRIVE__B)
1181 | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001182 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001183 status = Write16_0(state, SIO_PDR_MD1_CFG__A, 0x0000);
1184 if (status < 0)
1185 break;
1186 status = Write16_0(state, SIO_PDR_MD2_CFG__A, 0x0000);
1187 if (status < 0)
1188 break;
1189 status = Write16_0(state, SIO_PDR_MD3_CFG__A, 0x0000);
1190 if (status < 0)
1191 break;
1192 status = Write16_0(state, SIO_PDR_MD4_CFG__A, 0x0000);
1193 if (status < 0)
1194 break;
1195 status = Write16_0(state, SIO_PDR_MD5_CFG__A, 0x0000);
1196 if (status < 0)
1197 break;
1198 status = Write16_0(state, SIO_PDR_MD6_CFG__A, 0x0000);
1199 if (status < 0)
1200 break;
1201 status = Write16_0(state, SIO_PDR_MD7_CFG__A, 0x0000);
1202 if (status < 0)
1203 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001204 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001205 status = Write16_0(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
1206 if (status < 0)
1207 break;
1208 status = Write16_0(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
1209 if (status < 0)
1210 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001211 }
1212 /* Enable MB output over MPEG pads and ctl input */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001213 status = Write16_0(state, SIO_PDR_MON_CFG__A, 0x0000);
1214 if (status < 0)
1215 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001216 /* Write nomagic word to enable pdr reg write */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001217 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0x0000);
1218 if (status < 0)
1219 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001220 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001221 return status;
1222}
1223
1224static int MPEGTSDisable(struct drxk_state *state)
1225{
1226 return MPEGTSConfigurePins(state, false);
1227}
1228
1229static int BLChainCmd(struct drxk_state *state,
1230 u16 romOffset, u16 nrOfElements, u32 timeOut)
1231{
1232 u16 blStatus = 0;
1233 int status;
1234 unsigned long end;
1235
1236 mutex_lock(&state->mutex);
1237 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001238 status = Write16_0(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1239 if (status < 0)
1240 break;
1241 status = Write16_0(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1242 if (status < 0)
1243 break;
1244 status = Write16_0(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1245 if (status < 0)
1246 break;
1247 status = Write16_0(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1248 if (status < 0)
1249 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001250 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001251
1252 do {
1253 msleep(1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001254 status = Read16(state, SIO_BL_STATUS__A, &blStatus, 0);
1255 if (status < 0)
1256 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001257 } while ((blStatus == 0x1) &&
1258 ((time_is_after_jiffies(end))));
1259 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001260 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001261 mutex_unlock(&state->mutex);
1262 return -1;
1263 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001264 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001265 mutex_unlock(&state->mutex);
1266 return status;
1267}
1268
1269
1270static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001271 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001272{
1273 const u8 *pSrc = pMCImage;
1274 u16 Flags;
1275 u16 Drain;
1276 u32 Address;
1277 u16 nBlocks;
1278 u16 BlockSize;
1279 u16 BlockCRC;
1280 u32 offset = 0;
1281 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001282 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001283
1284 /* down the drain (we don care about MAGIC_WORD) */
1285 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001286 pSrc += sizeof(u16);
1287 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001288 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001289 pSrc += sizeof(u16);
1290 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001291
1292 for (i = 0; i < nBlocks; i += 1) {
1293 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001294 (pSrc[2] << 8) | pSrc[3];
1295 pSrc += sizeof(u32);
1296 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001297
1298 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001299 pSrc += sizeof(u16);
1300 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001301
1302 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001303 pSrc += sizeof(u16);
1304 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001305
1306 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001307 pSrc += sizeof(u16);
1308 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001309 status = WriteBlock(state, Address, BlockSize, pSrc, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001310 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001311 break;
1312 pSrc += BlockSize;
1313 offset += BlockSize;
1314 }
1315 return status;
1316}
1317
1318static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1319{
1320 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001321 u16 data = 0;
1322 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001323 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1324 unsigned long end;
1325
1326 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001327 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001328 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1329 }
1330
Oliver Endrissebc7de22011-07-03 13:49:44 -03001331 status = (Read16_0(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001332
1333 if (data == desiredStatus) {
1334 /* tokenring already has correct status */
1335 return status;
1336 }
1337 /* Disable/enable dvbt tokenring bridge */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001338 status =
1339 Write16_0(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001340
Oliver Endrissebc7de22011-07-03 13:49:44 -03001341 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001342 do {
1343 status = Read16_0(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1344 if (status < 0)
1345 break;
1346 } while ((data != desiredStatus) && ((time_is_after_jiffies(end))));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001347 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001348 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001349 return -1;
1350 }
1351 return status;
1352}
1353
1354static int MPEGTSStop(struct drxk_state *state)
1355{
1356 int status = 0;
1357 u16 fecOcSncMode = 0;
1358 u16 fecOcIprMode = 0;
1359
1360 do {
1361 /* Gracefull shutdown (byte boundaries) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001362 status = Read16_0(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1363 if (status < 0)
1364 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001365 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001366 status = Write16_0(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1367 if (status < 0)
1368 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001369
1370 /* Suppress MCLK during absence of data */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001371 status = Read16_0(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1372 if (status < 0)
1373 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001374 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001375 status = Write16_0(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1376 if (status < 0)
1377 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001378 } while (0);
1379 return status;
1380}
1381
1382static int scu_command(struct drxk_state *state,
1383 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001384 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001385{
1386#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1387#error DRXK register mapping no longer compatible with this routine!
1388#endif
1389 u16 curCmd = 0;
1390 int status;
1391 unsigned long end;
1392
1393 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1394 ((resultLen > 0) && (result == NULL)))
1395 return -1;
1396
1397 mutex_lock(&state->mutex);
1398 do {
1399 /* assume that the command register is ready
1400 since it is checked afterwards */
1401 u8 buffer[34];
1402 int cnt = 0, ii;
1403
Oliver Endrissebc7de22011-07-03 13:49:44 -03001404 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001405 buffer[cnt++] = (parameter[ii] & 0xFF);
1406 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1407 }
1408 buffer[cnt++] = (cmd & 0xFF);
1409 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1410
1411 WriteBlock(state, SCU_RAM_PARAM_0__A -
Oliver Endrissebc7de22011-07-03 13:49:44 -03001412 (parameterLen - 1), cnt, buffer, 0x00);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001413 /* Wait until SCU has processed command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001414 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001415 do {
1416 msleep(1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001417 status = Read16_0(state, SCU_RAM_COMMAND__A, &curCmd);
1418 if (status < 0)
1419 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001420 } while (!(curCmd == DRX_SCU_READY)
1421 && (time_is_after_jiffies(end)));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001422 if (curCmd != DRX_SCU_READY) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001423 printk(KERN_ERR "drxk: SCU not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001424 mutex_unlock(&state->mutex);
1425 return -1;
1426 }
1427 /* read results */
1428 if ((resultLen > 0) && (result != NULL)) {
1429 s16 err;
1430 int ii;
1431
Oliver Endrissebc7de22011-07-03 13:49:44 -03001432 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001433 status = Read16_0(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
1434 if (status < 0)
1435 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001436 }
1437
1438 /* Check if an error was reported by SCU */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001439 err = (s16) result[0];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001440
1441 /* check a few fixed error codes */
1442 if (err == SCU_RESULT_UNKSTD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001443 printk(KERN_ERR "drxk: SCU_RESULT_UNKSTD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001444 mutex_unlock(&state->mutex);
1445 return -1;
1446 } else if (err == SCU_RESULT_UNKCMD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001447 printk(KERN_ERR "drxk: SCU_RESULT_UNKCMD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001448 mutex_unlock(&state->mutex);
1449 return -1;
1450 }
1451 /* here it is assumed that negative means error,
1452 and positive no error */
1453 else if (err < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001454 printk(KERN_ERR "drxk: %s ERROR\n", __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001455 mutex_unlock(&state->mutex);
1456 return -1;
1457 }
1458 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001459 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001460 mutex_unlock(&state->mutex);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001461 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001462 printk(KERN_ERR "drxk: %s: status = %d\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001463
1464 return status;
1465}
1466
1467static int SetIqmAf(struct drxk_state *state, bool active)
1468{
1469 u16 data = 0;
1470 int status;
1471
Oliver Endrissebc7de22011-07-03 13:49:44 -03001472 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001473 /* Configure IQM */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001474 status = Read16_0(state, IQM_AF_STDBY__A, &data);
1475 if (status < 0)
1476 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001477 if (!active) {
1478 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1479 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1480 | IQM_AF_STDBY_STDBY_PD_STANDBY
1481 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
Oliver Endrissebc7de22011-07-03 13:49:44 -03001482 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1483 } else { /* active */
1484
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001485 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1486 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1487 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1488 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1489 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
Oliver Endrissebc7de22011-07-03 13:49:44 -03001490 );
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001491 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001492 status = Write16_0(state, IQM_AF_STDBY__A, data);
1493 if (status < 0)
1494 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001495 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001496 return status;
1497}
1498
Oliver Endrissebc7de22011-07-03 13:49:44 -03001499static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001500{
1501 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001502 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001503
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001504 /* Check arguments */
1505 if (mode == NULL)
1506 return -1;
1507
1508 switch (*mode) {
1509 case DRX_POWER_UP:
1510 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1511 break;
1512 case DRXK_POWER_DOWN_OFDM:
1513 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1514 break;
1515 case DRXK_POWER_DOWN_CORE:
1516 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1517 break;
1518 case DRXK_POWER_DOWN_PLL:
1519 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1520 break;
1521 case DRX_POWER_DOWN:
1522 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1523 break;
1524 default:
1525 /* Unknow sleep mode */
1526 return -1;
1527 break;
1528 }
1529
1530 /* If already in requested power mode, do nothing */
1531 if (state->m_currentPowerMode == *mode)
1532 return 0;
1533
1534 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001535 if (state->m_currentPowerMode != DRX_POWER_UP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001536 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001537 status = PowerUpDevice(state);
1538 if (status < 0)
1539 break;
1540 status = DVBTEnableOFDMTokenRing(state, true);
1541 if (status < 0)
1542 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001543 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001544 }
1545
1546 if (*mode == DRX_POWER_UP) {
1547 /* Restore analog & pin configuartion */
1548 } else {
1549 /* Power down to requested mode */
1550 /* Backup some register settings */
1551 /* Set pins with possible pull-ups connected
1552 to them in input mode */
1553 /* Analog power down */
1554 /* ADC power down */
1555 /* Power down device */
1556 /* stop all comm_exec */
1557 /* Stop and power down previous standard */
1558 do {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001559 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001560 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001561 status = MPEGTSStop(state);
1562 if (status < 0)
1563 break;
1564 status = PowerDownDVBT(state, false);
1565 if (status < 0)
1566 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001567 break;
1568 case OM_QAM_ITU_A:
1569 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001570 status = MPEGTSStop(state);
1571 if (status < 0)
1572 break;
1573 status = PowerDownQAM(state);
1574 if (status < 0)
1575 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001576 break;
1577 default:
1578 break;
1579 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001580 status = DVBTEnableOFDMTokenRing(state, false);
1581 if (status < 0)
1582 break;
1583 status = Write16_0(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1584 if (status < 0)
1585 break;
1586 status = Write16_0(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1587 if (status < 0)
1588 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001589
Oliver Endrissebc7de22011-07-03 13:49:44 -03001590 if (*mode != DRXK_POWER_DOWN_OFDM) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001591 state->m_HICfgCtrl |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03001592 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001593 status = HI_CfgCommand(state);
1594 if (status < 0)
1595 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001596 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001597 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001598 }
1599 state->m_currentPowerMode = *mode;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001600 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001601}
1602
1603static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1604{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001605 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001606 u16 cmdResult = 0;
1607 u16 data = 0;
1608 int status;
1609
1610 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001611 status = Read16_0(state, SCU_COMM_EXEC__A, &data);
1612 if (status < 0)
1613 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001614 if (data == SCU_COMM_EXEC_ACTIVE) {
1615 /* Send OFDM stop command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001616 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
1617 if (status < 0)
1618 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001619 /* Send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001620 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1621 if (status < 0)
1622 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001623 }
1624
1625 /* Reset datapath for OFDM, processors first */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001626 status = Write16_0(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1627 if (status < 0)
1628 break;
1629 status = Write16_0(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1630 if (status < 0)
1631 break;
1632 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1633 if (status < 0)
1634 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001635
1636 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001637 status = SetIqmAf(state, false);
1638 if (status < 0)
1639 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001640
1641 /* powerdown to OFDM mode */
1642 if (setPowerMode) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001643 status = CtrlPowerMode(state, &powerMode);
1644 if (status < 0)
1645 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001646 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001647 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001648 return status;
1649}
1650
Oliver Endrissebc7de22011-07-03 13:49:44 -03001651static int SetOperationMode(struct drxk_state *state,
1652 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001653{
1654 int status = 0;
1655
1656 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001657 Stop and power down previous standard
1658 TODO investigate total power down instead of partial
1659 power down depending on "previous" standard.
1660 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001661 do {
1662 /* disable HW lock indicator */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001663 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1664 if (status < 0)
1665 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001666
1667 if (state->m_OperationMode != oMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001668 switch (state->m_OperationMode) {
1669 /* OM_NONE was added for start up */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001670 case OM_NONE:
1671 break;
1672 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001673 status = MPEGTSStop(state);
1674 if (status < 0)
1675 break;
1676 status = PowerDownDVBT(state, true);
1677 if (status < 0)
1678 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001679 state->m_OperationMode = OM_NONE;
1680 break;
1681 case OM_QAM_ITU_B:
1682 status = -1;
1683 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001684 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001685 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001686 status = MPEGTSStop(state);
1687 if (status < 0)
1688 break;
1689 status = PowerDownQAM(state);
1690 if (status < 0)
1691 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001692 state->m_OperationMode = OM_NONE;
1693 break;
1694 default:
1695 status = -1;
1696 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001697 status = status;
1698 if (status < 0)
1699 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001700
1701 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001702 Power up new standard
1703 */
1704 switch (oMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001705 case OM_DVBT:
1706 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001707 status = SetDVBTStandard(state, oMode);
1708 if (status < 0)
1709 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001710 break;
1711 case OM_QAM_ITU_B:
1712 status = -1;
1713 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001714 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001715 case OM_QAM_ITU_C:
1716 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001717 status = SetQAMStandard(state, oMode);
1718 if (status < 0)
1719 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001720 break;
1721 default:
1722 status = -1;
1723 }
1724 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001725 status = status;
1726 if (status < 0)
1727 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001728 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001729 return 0;
1730}
1731
1732static int Start(struct drxk_state *state, s32 offsetFreq,
1733 s32 IntermediateFrequency)
1734{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001735 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001736
1737 do {
1738 u16 IFreqkHz;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001739 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001740
1741 if (state->m_DrxkState != DRXK_STOPPED &&
1742 state->m_DrxkState != DRXK_DTV_STARTED) {
1743 status = -1;
1744 break;
1745 }
1746 state->m_bMirrorFreqSpect =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001747 (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001748
1749 if (IntermediateFrequency < 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001750 state->m_bMirrorFreqSpect =
1751 !state->m_bMirrorFreqSpect;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001752 IntermediateFrequency = -IntermediateFrequency;
1753 }
1754
Oliver Endrissebc7de22011-07-03 13:49:44 -03001755 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001756 case OM_QAM_ITU_A:
1757 case OM_QAM_ITU_C:
1758 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001759 status = SetQAM(state, IFreqkHz, OffsetkHz);
1760 if (status < 0)
1761 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001762 state->m_DrxkState = DRXK_DTV_STARTED;
1763 break;
1764 case OM_DVBT:
1765 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001766 status = MPEGTSStop(state);
1767 if (status < 0)
1768 break;
1769 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1770 if (status < 0)
1771 break;
1772 status = DVBTStart(state);
1773 if (status < 0)
1774 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001775 state->m_DrxkState = DRXK_DTV_STARTED;
1776 break;
1777 default:
1778 break;
1779 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001780 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001781 return status;
1782}
1783
1784static int ShutDown(struct drxk_state *state)
1785{
1786 MPEGTSStop(state);
1787 return 0;
1788}
1789
Oliver Endrissebc7de22011-07-03 13:49:44 -03001790static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1791 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001792{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001793 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001794
1795 if (pLockStatus == NULL)
1796 return -1;
1797
1798 *pLockStatus = NOT_LOCKED;
1799
1800 /* define the SCU command code */
1801 switch (state->m_OperationMode) {
1802 case OM_QAM_ITU_A:
1803 case OM_QAM_ITU_B:
1804 case OM_QAM_ITU_C:
1805 status = GetQAMLockStatus(state, pLockStatus);
1806 break;
1807 case OM_DVBT:
1808 status = GetDVBTLockStatus(state, pLockStatus);
1809 break;
1810 default:
1811 break;
1812 }
1813 return status;
1814}
1815
1816static int MPEGTSStart(struct drxk_state *state)
1817{
1818 int status = 0;
1819
1820 u16 fecOcSncMode = 0;
1821
1822 do {
1823 /* Allow OC to sync again */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001824 status = Read16_0(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1825 if (status < 0)
1826 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001827 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001828 status = Write16_0(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1829 if (status < 0)
1830 break;
1831 status = Write16_0(state, FEC_OC_SNC_UNLOCK__A, 1);
1832 if (status < 0)
1833 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001834 } while (0);
1835 return status;
1836}
1837
1838static int MPEGTSDtoInit(struct drxk_state *state)
1839{
1840 int status = -1;
1841
1842 do {
1843 /* Rate integration settings */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001844 status = Write16_0(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1845 if (status < 0)
1846 break;
1847 status = Write16_0(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1848 if (status < 0)
1849 break;
1850 status = Write16_0(state, FEC_OC_RCN_GAIN__A, 0x000A);
1851 if (status < 0)
1852 break;
1853 status = Write16_0(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1854 if (status < 0)
1855 break;
1856 status = Write16_0(state, FEC_OC_AVR_PARM_B__A, 0x0006);
1857 if (status < 0)
1858 break;
1859 status = Write16_0(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
1860 if (status < 0)
1861 break;
1862 status = Write16_0(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
1863 if (status < 0)
1864 break;
1865 status = Write16_0(state, FEC_OC_TMD_COUNT__A, 0x03F4);
1866 if (status < 0)
1867 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001868
1869 /* Additional configuration */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001870 status = Write16_0(state, FEC_OC_OCR_INVERT__A, 0);
1871 if (status < 0)
1872 break;
1873 status = Write16_0(state, FEC_OC_SNC_LWM__A, 2);
1874 if (status < 0)
1875 break;
1876 status = Write16_0(state, FEC_OC_SNC_HWM__A, 12);
1877 if (status < 0)
1878 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001879 } while (0);
1880 return status;
1881}
1882
Oliver Endrissebc7de22011-07-03 13:49:44 -03001883static int MPEGTSDtoSetup(struct drxk_state *state,
1884 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001885{
1886 int status = -1;
1887
Oliver Endrissebc7de22011-07-03 13:49:44 -03001888 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
1889 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
1890 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
1891 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
1892 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
1893 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
1894 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001895 u16 fecOcTmdMode = 0;
1896 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001897 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001898 bool staticCLK = false;
1899
1900 do {
1901 /* Check insertion of the Reed-Solomon parity bytes */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001902 status = Read16_0(state, FEC_OC_MODE__A, &fecOcRegMode);
1903 if (status < 0)
1904 break;
1905 status = Read16_0(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
1906 if (status < 0)
1907 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001908 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001909 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
1910 if (state->m_insertRSByte == true) {
1911 /* enable parity symbol forward */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001912 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001913 /* MVAL disable during parity bytes */
1914 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
1915 /* TS burst length to 204 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001916 fecOcDtoBurstLen = 204;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001917 }
1918
1919 /* Check serial or parrallel output */
1920 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
1921 if (state->m_enableParallel == false) {
1922 /* MPEG data output is serial -> set ipr_mode[0] */
1923 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
1924 }
1925
1926 switch (oMode) {
1927 case OM_DVBT:
1928 maxBitRate = state->m_DVBTBitrate;
1929 fecOcTmdMode = 3;
1930 fecOcRcnCtlRate = 0xC00000;
1931 staticCLK = state->m_DVBTStaticCLK;
1932 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001933 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001934 case OM_QAM_ITU_C:
1935 fecOcTmdMode = 0x0004;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001936 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001937 maxBitRate = state->m_DVBCBitrate;
1938 staticCLK = state->m_DVBCStaticCLK;
1939 break;
1940 default:
1941 status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001942 } /* switch (standard) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001943 status = status;
1944 if (status < 0)
1945 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001946
1947 /* Configure DTO's */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001948 if (staticCLK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001949 u32 bitRate = 0;
1950
1951 /* Rational DTO for MCLK source (static MCLK rate),
1952 Dynamic DTO for optimal grouping
1953 (avoid intra-packet gaps),
1954 DTO offset enable to sync TS burst with MSTRT */
1955 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
1956 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
1957 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
1958 FEC_OC_FCT_MODE_VIRT_ENA__M);
1959
1960 /* Check user defined bitrate */
1961 bitRate = maxBitRate;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001962 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001963 bitRate = 75900000UL;
1964 }
1965 /* Rational DTO period:
1966 dto_period = (Fsys / bitrate) - 2
1967
1968 Result should be floored,
1969 to make sure >= requested bitrate
Oliver Endrissebc7de22011-07-03 13:49:44 -03001970 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001971 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
1972 * 1000) / bitRate);
1973 if (fecOcDtoPeriod <= 2)
1974 fecOcDtoPeriod = 0;
1975 else
1976 fecOcDtoPeriod -= 2;
1977 fecOcTmdIntUpdRate = 8;
1978 } else {
1979 /* (commonAttr->staticCLK == false) => dynamic mode */
1980 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
1981 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
1982 fecOcTmdIntUpdRate = 5;
1983 }
1984
1985 /* Write appropriate registers with requested configuration */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001986 status = Write16_0(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
1987 if (status < 0)
1988 break;
1989 status = Write16_0(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
1990 if (status < 0)
1991 break;
1992 status = Write16_0(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
1993 if (status < 0)
1994 break;
1995 status = Write16_0(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
1996 if (status < 0)
1997 break;
1998 status = Write16_0(state, FEC_OC_MODE__A, fecOcRegMode);
1999 if (status < 0)
2000 break;
2001 status = Write16_0(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2002 if (status < 0)
2003 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002004
2005 /* Rate integration settings */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002006 status = Write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate, 0);
2007 if (status < 0)
2008 break;
2009 status = Write16_0(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2010 if (status < 0)
2011 break;
2012 status = Write16_0(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2013 if (status < 0)
2014 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002015 } while (0);
2016 return status;
2017}
2018
2019static int MPEGTSConfigurePolarity(struct drxk_state *state)
2020{
2021 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002022 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002023
2024 /* Data mask for the output data byte */
2025 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002026 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2027 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2028 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2029 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002030
2031 /* Control selective inversion of output bits */
2032 fecOcRegIprInvert &= (~(InvertDataMask));
2033 if (state->m_invertDATA == true)
2034 fecOcRegIprInvert |= InvertDataMask;
2035 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2036 if (state->m_invertERR == true)
2037 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2038 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2039 if (state->m_invertSTR == true)
2040 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2041 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2042 if (state->m_invertVAL == true)
2043 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2044 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2045 if (state->m_invertCLK == true)
2046 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002047 status = Write16_0(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002048 return status;
2049}
2050
2051#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2052
2053static int SetAgcRf(struct drxk_state *state,
2054 struct SCfgAgc *pAgcCfg, bool isDTV)
2055{
2056 int status = 0;
2057 struct SCfgAgc *pIfAgcSettings;
2058
2059 if (pAgcCfg == NULL)
2060 return -1;
2061
2062 do {
2063 u16 data = 0;
2064
2065 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002066 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002067
2068 /* Enable RF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002069 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2070 if (status < 0)
2071 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002072 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002073 status = Write16_0(state, IQM_AF_STDBY__A, data);
2074 if (status < 0)
2075 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002076
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002077 status = Read16(state, SCU_RAM_AGC_CONFIG__A, &data, 0);
2078 if (status < 0)
2079 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002080
2081 /* Enable SCU RF AGC loop */
2082 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2083
2084 /* Polarity */
2085 if (state->m_RfAgcPol)
2086 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2087 else
2088 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002089 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2090 if (status < 0)
2091 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002092
2093 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002094 status = Read16(state, SCU_RAM_AGC_KI_RED__A, &data, 0);
2095 if (status < 0)
2096 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002097
2098 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2099 data |= (~(pAgcCfg->speed <<
2100 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2101 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2102
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002103 status = Write16_0(state, SCU_RAM_AGC_KI_RED__A, data);
2104 if (status < 0)
2105 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002106
2107 if (IsDVBT(state))
2108 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2109 else if (IsQAM(state))
2110 pIfAgcSettings = &state->m_qamIfAgcCfg;
2111 else
2112 pIfAgcSettings = &state->m_atvIfAgcCfg;
2113 if (pIfAgcSettings == NULL)
2114 return -1;
2115
2116 /* Set TOP, only if IF-AGC is in AUTO mode */
2117 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002118 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
2119 if (status < 0)
2120 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002121
2122 /* Cut-Off current */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002123 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2124 if (status < 0)
2125 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002126
2127 /* Max. output level */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002128 status = Write16_0(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2129 if (status < 0)
2130 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002131
2132 break;
2133
2134 case DRXK_AGC_CTRL_USER:
2135 /* Enable RF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002136 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2137 if (status < 0)
2138 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002139 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002140 status = Write16_0(state, IQM_AF_STDBY__A, data);
2141 if (status < 0)
2142 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002143
2144 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002145 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2146 if (status < 0)
2147 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002148 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2149 if (state->m_RfAgcPol)
2150 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2151 else
2152 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002153 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2154 if (status < 0)
2155 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002156
2157 /* SCU c.o.c. to 0, enabling full control range */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002158 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2159 if (status < 0)
2160 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002161
2162 /* Write value to output pin */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002163 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2164 if (status < 0)
2165 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002166 break;
2167
Oliver Endrissebc7de22011-07-03 13:49:44 -03002168 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002169 /* Disable RF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002170 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2171 if (status < 0)
2172 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002173 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002174 status = Write16_0(state, IQM_AF_STDBY__A, data);
2175 if (status < 0)
2176 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002177
2178 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002179 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2180 if (status < 0)
2181 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002182 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002183 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2184 if (status < 0)
2185 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002186 break;
2187
2188 default:
2189 return -1;
2190
Oliver Endrissebc7de22011-07-03 13:49:44 -03002191 } /* switch (agcsettings->ctrlMode) */
2192 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002193 return status;
2194}
2195
2196#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2197
Oliver Endrissebc7de22011-07-03 13:49:44 -03002198static int SetAgcIf(struct drxk_state *state,
2199 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002200{
2201 u16 data = 0;
2202 int status = 0;
2203 struct SCfgAgc *pRfAgcSettings;
2204
2205 do {
2206 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002207 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002208
2209 /* Enable IF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002210 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2211 if (status < 0)
2212 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002213 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002214 status = Write16_0(state, IQM_AF_STDBY__A, data);
2215 if (status < 0)
2216 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002217
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002218 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2219 if (status < 0)
2220 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002221
2222 /* Enable SCU IF AGC loop */
2223 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2224
2225 /* Polarity */
2226 if (state->m_IfAgcPol)
2227 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2228 else
2229 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002230 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2231 if (status < 0)
2232 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002233
2234 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002235 status = Read16_0(state, SCU_RAM_AGC_KI_RED__A, &data);
2236 if (status < 0)
2237 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002238 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2239 data |= (~(pAgcCfg->speed <<
2240 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2241 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2242
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002243 status = Write16_0(state, SCU_RAM_AGC_KI_RED__A, data);
2244 if (status < 0)
2245 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002246
2247 if (IsQAM(state))
2248 pRfAgcSettings = &state->m_qamRfAgcCfg;
2249 else
2250 pRfAgcSettings = &state->m_atvRfAgcCfg;
2251 if (pRfAgcSettings == NULL)
2252 return -1;
2253 /* Restore TOP */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002254 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2255 if (status < 0)
2256 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002257 break;
2258
Oliver Endrissebc7de22011-07-03 13:49:44 -03002259 case DRXK_AGC_CTRL_USER:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002260
2261 /* Enable IF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002262 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2263 if (status < 0)
2264 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002265 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002266 status = Write16_0(state, IQM_AF_STDBY__A, data);
2267 if (status < 0)
2268 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002269
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002270 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2271 if (status < 0)
2272 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002273
2274 /* Disable SCU IF AGC loop */
2275 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2276
2277 /* Polarity */
2278 if (state->m_IfAgcPol)
2279 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2280 else
2281 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002282 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2283 if (status < 0)
2284 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002285
2286 /* Write value to output pin */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002287 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2288 if (status < 0)
2289 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002290 break;
2291
Oliver Endrissebc7de22011-07-03 13:49:44 -03002292 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002293
2294 /* Disable If AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002295 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2296 if (status < 0)
2297 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002298 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002299 status = Write16_0(state, IQM_AF_STDBY__A, data);
2300 if (status < 0)
2301 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002302
2303 /* Disable SCU IF AGC loop */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002304 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2305 if (status < 0)
2306 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002307 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002308 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2309 if (status < 0)
2310 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002311 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002312 } /* switch (agcSettingsIf->ctrlMode) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002313
2314 /* always set the top to support
2315 configurations without if-loop */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002316 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2317 if (status < 0)
2318 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002319
2320
Oliver Endrissebc7de22011-07-03 13:49:44 -03002321 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002322 return status;
2323}
2324
2325static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2326{
2327 u16 agcDacLvl;
2328 int status = Read16_0(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2329
2330 *pValue = 0;
2331
Oliver Endrissebc7de22011-07-03 13:49:44 -03002332 if (status == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002333 u16 Level = 0;
2334 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2335 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2336 if (Level < 14000)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002337 *pValue = (14000 - Level) / 4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002338 else
2339 *pValue = 0;
2340 }
2341 return status;
2342}
2343
Oliver Endrissebc7de22011-07-03 13:49:44 -03002344static int GetQAMSignalToNoise(struct drxk_state *state,
2345 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002346{
2347 int status = 0;
2348
2349 do {
2350 /* MER calculation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002351 u16 qamSlErrPower = 0; /* accum. error between
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002352 raw and sliced symbols */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002353 u32 qamSlSigPower = 0; /* used for MER, depends of
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002354 QAM constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002355 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002356
2357 /* get the register value needed for MER */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002358 status = Read16_0(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2359 if (status < 0)
2360 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002361
Oliver Endrissebc7de22011-07-03 13:49:44 -03002362 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002363 case QAM_16:
2364 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2365 break;
2366 case QAM_32:
2367 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2368 break;
2369 case QAM_64:
2370 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2371 break;
2372 case QAM_128:
2373 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2374 break;
2375 default:
2376 case QAM_256:
2377 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2378 break;
2379 }
2380
2381 if (qamSlErrPower > 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002382 qamSlMer = Log10Times100(qamSlSigPower) -
2383 Log10Times100((u32) qamSlErrPower);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002384 }
2385 *pSignalToNoise = qamSlMer;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002386 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002387 return status;
2388}
2389
Oliver Endrissebc7de22011-07-03 13:49:44 -03002390static int GetDVBTSignalToNoise(struct drxk_state *state,
2391 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002392{
2393 int status = 0;
2394
Oliver Endrissebc7de22011-07-03 13:49:44 -03002395 u16 regData = 0;
2396 u32 EqRegTdSqrErrI = 0;
2397 u32 EqRegTdSqrErrQ = 0;
2398 u16 EqRegTdSqrErrExp = 0;
2399 u16 EqRegTdTpsPwrOfs = 0;
2400 u16 EqRegTdReqSmbCnt = 0;
2401 u32 tpsCnt = 0;
2402 u32 SqrErrIQ = 0;
2403 u32 a = 0;
2404 u32 b = 0;
2405 u32 c = 0;
2406 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002407 u16 transmissionParams = 0;
2408
2409 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002410 status = Read16_0(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2411 if (status < 0)
2412 break;
2413 status = Read16_0(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2414 if (status < 0)
2415 break;
2416 status = Read16_0(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2417 if (status < 0)
2418 break;
2419 status = Read16_0(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2420 if (status < 0)
2421 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002422 /* Extend SQR_ERR_I operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002423 EqRegTdSqrErrI = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002424 if ((EqRegTdSqrErrExp > 11) &&
2425 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2426 EqRegTdSqrErrI += 0x00010000UL;
2427 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002428 status = Read16_0(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2429 if (status < 0)
2430 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002431 /* Extend SQR_ERR_Q operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002432 EqRegTdSqrErrQ = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002433 if ((EqRegTdSqrErrExp > 11) &&
2434 (EqRegTdSqrErrQ < 0x00000FFFUL))
2435 EqRegTdSqrErrQ += 0x00010000UL;
2436
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002437 status = Read16_0(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2438 if (status < 0)
2439 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002440
2441 /* Check input data for MER */
2442
2443 /* MER calculation (in 0.1 dB) without math.h */
2444 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2445 iMER = 0;
2446 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2447 /* No error at all, this must be the HW reset value
2448 * Apparently no first measurement yet
2449 * Set MER to 0.0 */
2450 iMER = 0;
2451 } else {
2452 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03002453 EqRegTdSqrErrExp;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002454 if ((transmissionParams &
2455 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2456 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2457 tpsCnt = 17;
2458 else
2459 tpsCnt = 68;
2460
2461 /* IMER = 100 * log10 (x)
2462 where x = (EqRegTdTpsPwrOfs^2 *
2463 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2464
2465 => IMER = a + b -c
2466 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2467 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2468 c = 100 * log10 (SqrErrIQ)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002469 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002470
2471 /* log(x) x = 9bits * 9bits->18 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002472 a = Log10Times100(EqRegTdTpsPwrOfs *
2473 EqRegTdTpsPwrOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002474 /* log(x) x = 16bits * 7bits->23 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002475 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002476 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2477 c = Log10Times100(SqrErrIQ);
2478
2479 iMER = a + b;
2480 /* No negative MER, clip to zero */
2481 if (iMER > c)
2482 iMER -= c;
2483 else
2484 iMER = 0;
2485 }
2486 *pSignalToNoise = iMER;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002487 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002488
2489 return status;
2490}
2491
2492static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2493{
2494 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002495 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002496 case OM_DVBT:
2497 return GetDVBTSignalToNoise(state, pSignalToNoise);
2498 case OM_QAM_ITU_A:
2499 case OM_QAM_ITU_C:
2500 return GetQAMSignalToNoise(state, pSignalToNoise);
2501 default:
2502 break;
2503 }
2504 return 0;
2505}
2506
2507#if 0
2508static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2509{
2510 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2511 int status = 0;
2512
Oliver Endrissebc7de22011-07-03 13:49:44 -03002513 static s32 QE_SN[] = {
2514 51, /* QPSK 1/2 */
2515 69, /* QPSK 2/3 */
2516 79, /* QPSK 3/4 */
2517 89, /* QPSK 5/6 */
2518 97, /* QPSK 7/8 */
2519 108, /* 16-QAM 1/2 */
2520 131, /* 16-QAM 2/3 */
2521 146, /* 16-QAM 3/4 */
2522 156, /* 16-QAM 5/6 */
2523 160, /* 16-QAM 7/8 */
2524 165, /* 64-QAM 1/2 */
2525 187, /* 64-QAM 2/3 */
2526 202, /* 64-QAM 3/4 */
2527 216, /* 64-QAM 5/6 */
2528 225, /* 64-QAM 7/8 */
2529 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002530
2531 *pQuality = 0;
2532
2533 do {
2534 s32 SignalToNoise = 0;
2535 u16 Constellation = 0;
2536 u16 CodeRate = 0;
2537 u32 SignalToNoiseRel;
2538 u32 BERQuality;
2539
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002540 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2541 if (status < 0)
2542 break;
2543 status = Read16_0(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
2544 if (status < 0)
2545 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002546 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2547
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002548 status = Read16_0(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
2549 if (status < 0)
2550 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002551 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2552
2553 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2554 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2555 break;
2556 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002557 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002558 BERQuality = 100;
2559
Oliver Endrissebc7de22011-07-03 13:49:44 -03002560 if (SignalToNoiseRel < -70)
2561 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002562 else if (SignalToNoiseRel < 30)
2563 *pQuality = ((SignalToNoiseRel + 70) *
2564 BERQuality) / 100;
2565 else
2566 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002567 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002568 return 0;
2569};
2570
Oliver Endrissebc7de22011-07-03 13:49:44 -03002571static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002572{
2573 int status = 0;
2574 *pQuality = 0;
2575
2576 do {
2577 u32 SignalToNoise = 0;
2578 u32 BERQuality = 100;
2579 u32 SignalToNoiseRel = 0;
2580
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002581 status = GetQAMSignalToNoise(state, &SignalToNoise);
2582 if (status < 0)
2583 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002584
Oliver Endrissebc7de22011-07-03 13:49:44 -03002585 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002586 case QAM_16:
2587 SignalToNoiseRel = SignalToNoise - 200;
2588 break;
2589 case QAM_32:
2590 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002591 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002592 case QAM_64:
2593 SignalToNoiseRel = SignalToNoise - 260;
2594 break;
2595 case QAM_128:
2596 SignalToNoiseRel = SignalToNoise - 290;
2597 break;
2598 default:
2599 case QAM_256:
2600 SignalToNoiseRel = SignalToNoise - 320;
2601 break;
2602 }
2603
2604 if (SignalToNoiseRel < -70)
2605 *pQuality = 0;
2606 else if (SignalToNoiseRel < 30)
2607 *pQuality = ((SignalToNoiseRel + 70) *
2608 BERQuality) / 100;
2609 else
2610 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002611 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002612
2613 return status;
2614}
2615
2616static int GetQuality(struct drxk_state *state, s32 *pQuality)
2617{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002618 switch (state->m_OperationMode) {
2619 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002620 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002621 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002622 return GetDVBCQuality(state, pQuality);
2623 default:
2624 break;
2625 }
2626
2627 return 0;
2628}
2629#endif
2630
2631/* Free data ram in SIO HI */
2632#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2633#define SIO_HI_RA_RAM_USR_END__A 0x420060
2634
2635#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2636#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2637#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2638#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2639
2640#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2641#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2642#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2643
2644static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2645{
2646 int status;
2647
2648 if (state->m_DrxkState == DRXK_UNINITIALIZED)
2649 return -1;
2650 if (state->m_DrxkState == DRXK_POWERED_DOWN)
2651 return -1;
2652
2653 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002654 status = Write16_0(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2655 if (status < 0)
2656 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002657 if (bEnableBridge) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002658 status = Write16_0(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
2659 if (status < 0)
2660 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002661 } else {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002662 status = Write16_0(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2663 if (status < 0)
2664 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002665 }
2666
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002667 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2668 if (status < 0)
2669 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002670 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002671 return status;
2672}
2673
Oliver Endrissebc7de22011-07-03 13:49:44 -03002674static int SetPreSaw(struct drxk_state *state,
2675 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002676{
2677 int status;
2678
Oliver Endrissebc7de22011-07-03 13:49:44 -03002679 if ((pPreSawCfg == NULL)
2680 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002681 return -1;
2682
2683 status = Write16_0(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
2684 return status;
2685}
2686
2687static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002688 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002689{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002690 u16 blStatus = 0;
2691 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2692 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2693 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002694 unsigned long end;
2695
2696 mutex_lock(&state->mutex);
2697 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002698 status = Write16_0(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2699 if (status < 0)
2700 break;
2701 status = Write16_0(state, SIO_BL_TGT_HDR__A, blockbank);
2702 if (status < 0)
2703 break;
2704 status = Write16_0(state, SIO_BL_TGT_ADDR__A, offset);
2705 if (status < 0)
2706 break;
2707 status = Write16_0(state, SIO_BL_SRC_ADDR__A, romOffset);
2708 if (status < 0)
2709 break;
2710 status = Write16_0(state, SIO_BL_SRC_LEN__A, nrOfElements);
2711 if (status < 0)
2712 break;
2713 status = Write16_0(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2714 if (status < 0)
2715 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002716
Oliver Endrissebc7de22011-07-03 13:49:44 -03002717 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002718 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002719 status = Read16_0(state, SIO_BL_STATUS__A, &blStatus);
2720 if (status < 0)
2721 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002722 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002723 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03002724 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002725 mutex_unlock(&state->mutex);
2726 return -1;
2727 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03002728 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002729 mutex_unlock(&state->mutex);
2730 return status;
2731
2732}
2733
Oliver Endrissebc7de22011-07-03 13:49:44 -03002734static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002735{
2736 u16 data = 0;
2737 int status;
2738
2739 do {
2740 /* Start measurement */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002741 status = Write16_0(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2742 if (status < 0)
2743 break;
2744 status = Write16_0(state, IQM_AF_START_LOCK__A, 1);
2745 if (status < 0)
2746 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002747
2748 *count = 0;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002749 status = Read16_0(state, IQM_AF_PHASE0__A, &data);
2750 if (status < 0)
2751 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002752 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002753 *count = *count + 1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002754 status = Read16_0(state, IQM_AF_PHASE1__A, &data);
2755 if (status < 0)
2756 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002757 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002758 *count = *count + 1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002759 status = Read16_0(state, IQM_AF_PHASE2__A, &data);
2760 if (status < 0)
2761 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002762 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002763 *count = *count + 1;
2764 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002765 return status;
2766}
2767
2768static int ADCSynchronization(struct drxk_state *state)
2769{
2770 u16 count = 0;
2771 int status;
2772
2773 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002774 status = ADCSyncMeasurement(state, &count);
2775 if (status < 0)
2776 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002777
Oliver Endrissebc7de22011-07-03 13:49:44 -03002778 if (count == 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002779 /* Try sampling on a diffrent edge */
2780 u16 clkNeg = 0;
2781
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002782 status = Read16_0(state, IQM_AF_CLKNEG__A, &clkNeg);
2783 if (status < 0)
2784 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002785 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002786 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2787 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2788 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002789 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002790 } else {
2791 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2792 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002793 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002794 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002795 status = Write16_0(state, IQM_AF_CLKNEG__A, clkNeg);
2796 if (status < 0)
2797 break;
2798 status = ADCSyncMeasurement(state, &count);
2799 if (status < 0)
2800 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002801 }
2802
2803 if (count < 2)
2804 status = -1;
2805 } while (0);
2806 return status;
2807}
2808
2809static int SetFrequencyShifter(struct drxk_state *state,
2810 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002811 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002812{
2813 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002814 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002815 u32 fmFrequencyShift = 0;
2816 bool tunerMirror = !state->m_bMirrorFreqSpect;
2817 u32 adcFreq;
2818 bool adcFlip;
2819 int status;
2820 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002821 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002822 u32 frequencyShift;
2823 bool imageToSelect;
2824
2825 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03002826 Program frequency shifter
2827 No need to account for mirroring on RF
2828 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002829 if (isDTV) {
2830 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
2831 (state->m_OperationMode == OM_QAM_ITU_C) ||
2832 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03002833 selectPosImage = true;
2834 else
2835 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002836 }
2837 if (tunerMirror)
2838 /* tuner doesn't mirror */
2839 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03002840 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002841 else
2842 /* tuner mirrors */
2843 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002844 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002845 if (ifFreqActual > samplingFrequency / 2) {
2846 /* adc mirrors */
2847 adcFreq = samplingFrequency - ifFreqActual;
2848 adcFlip = true;
2849 } else {
2850 /* adc doesn't mirror */
2851 adcFreq = ifFreqActual;
2852 adcFlip = false;
2853 }
2854
2855 frequencyShift = adcFreq;
2856 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03002857 adcFlip ^ selectPosImage;
2858 state->m_IqmFsRateOfs =
2859 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002860
2861 if (imageToSelect)
2862 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
2863
2864 /* Program frequency shifter with tuner offset compensation */
2865 /* frequencyShift += tunerFreqOffset; TODO */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002866 status = Write32(state, IQM_FS_RATE_OFS_LO__A,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002867 state->m_IqmFsRateOfs, 0);
2868 return status;
2869}
2870
2871static int InitAGC(struct drxk_state *state, bool isDTV)
2872{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002873 u16 ingainTgt = 0;
2874 u16 ingainTgtMin = 0;
2875 u16 ingainTgtMax = 0;
2876 u16 clpCyclen = 0;
2877 u16 clpSumMin = 0;
2878 u16 clpDirTo = 0;
2879 u16 snsSumMin = 0;
2880 u16 snsSumMax = 0;
2881 u16 clpSumMax = 0;
2882 u16 snsDirTo = 0;
2883 u16 kiInnergainMin = 0;
2884 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002885 u16 ifIaccuHiTgtMin = 0;
2886 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002887 u16 data = 0;
2888 u16 fastClpCtrlDelay = 0;
2889 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002890 int status = 0;
2891
2892 do {
2893 /* Common settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002894 snsSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002895 ifIaccuHiTgtMin = 2047;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002896 clpCyclen = 500;
2897 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002898
2899 if (IsQAM(state)) {
2900 /* Standard specific settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002901 clpSumMin = 8;
2902 clpDirTo = (u16) -9;
2903 clpCtrlMode = 0;
2904 snsSumMin = 8;
2905 snsDirTo = (u16) -9;
2906 kiInnergainMin = (u16) -1030;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002907 } else
2908 status = -1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002909 status = (status);
2910 if (status < 0)
2911 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002912 if (IsQAM(state)) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002913 ifIaccuHiTgtMax = 0x2380;
2914 ifIaccuHiTgt = 0x2380;
2915 ingainTgtMin = 0x0511;
2916 ingainTgt = 0x0511;
2917 ingainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002918 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002919 state->m_qamIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002920 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002921 ifIaccuHiTgtMax = 0x1200;
2922 ifIaccuHiTgt = 0x1200;
2923 ingainTgtMin = 13424;
2924 ingainTgt = 13424;
2925 ingainTgtMax = 30000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002926 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002927 state->m_dvbtIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002928 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002929 status = Write16_0(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
2930 if (status < 0)
2931 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002932
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002933 status = Write16_0(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
2934 if (status < 0)
2935 break;
2936 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
2937 if (status < 0)
2938 break;
2939 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
2940 if (status < 0)
2941 break;
2942 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
2943 if (status < 0)
2944 break;
2945 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
2946 if (status < 0)
2947 break;
2948 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
2949 if (status < 0)
2950 break;
2951 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
2952 if (status < 0)
2953 break;
2954 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
2955 if (status < 0)
2956 break;
2957 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
2958 if (status < 0)
2959 break;
2960 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
2961 if (status < 0)
2962 break;
2963 status = Write16_0(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
2964 if (status < 0)
2965 break;
2966 status = Write16_0(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
2967 if (status < 0)
2968 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002969
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002970 status = Write16_0(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
2971 if (status < 0)
2972 break;
2973 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
2974 if (status < 0)
2975 break;
2976 status = Write16_0(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
2977 if (status < 0)
2978 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002979
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002980 status = Write16_0(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
2981 if (status < 0)
2982 break;
2983 status = Write16_0(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
2984 if (status < 0)
2985 break;
2986 status = Write16_0(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
2987 if (status < 0)
2988 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002989
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002990 status = Write16_0(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
2991 if (status < 0)
2992 break;
2993 status = Write16_0(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
2994 if (status < 0)
2995 break;
2996 status = Write16_0(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
2997 if (status < 0)
2998 break;
2999 status = Write16_0(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3000 if (status < 0)
3001 break;
3002 status = Write16_0(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3003 if (status < 0)
3004 break;
3005 status = Write16_0(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3006 if (status < 0)
3007 break;
3008 status = Write16_0(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3009 if (status < 0)
3010 break;
3011 status = Write16_0(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3012 if (status < 0)
3013 break;
3014 status = Write16_0(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3015 if (status < 0)
3016 break;
3017 status = Write16_0(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3018 if (status < 0)
3019 break;
3020 status = Write16_0(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3021 if (status < 0)
3022 break;
3023 status = Write16_0(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3024 if (status < 0)
3025 break;
3026 status = Write16_0(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3027 if (status < 0)
3028 break;
3029 status = Write16_0(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3030 if (status < 0)
3031 break;
3032 status = Write16_0(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3033 if (status < 0)
3034 break;
3035 status = Write16_0(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3036 if (status < 0)
3037 break;
3038 status = Write16_0(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3039 if (status < 0)
3040 break;
3041 status = Write16_0(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3042 if (status < 0)
3043 break;
3044 status = Write16_0(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3045 if (status < 0)
3046 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003047
3048 /* Initialize inner-loop KI gain factors */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003049 status = Read16_0(state, SCU_RAM_AGC_KI__A, &data);
3050 if (status < 0)
3051 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003052 if (IsQAM(state)) {
3053 data = 0x0657;
3054 data &= ~SCU_RAM_AGC_KI_RF__M;
3055 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3056 data &= ~SCU_RAM_AGC_KI_IF__M;
3057 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3058 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003059 status = Write16_0(state, SCU_RAM_AGC_KI__A, data);
3060 if (status < 0)
3061 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003062 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003063 return status;
3064}
3065
Oliver Endrissebc7de22011-07-03 13:49:44 -03003066static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003067{
3068 int status;
3069
3070 do {
3071 if (packetErr == NULL) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003072 status = Write16_0(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3073 if (status < 0)
3074 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003075 } else {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003076 status = Read16_0(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3077 if (status < 0)
3078 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003079 }
3080 } while (0);
3081 return status;
3082}
3083
3084static int DVBTScCommand(struct drxk_state *state,
3085 u16 cmd, u16 subcmd,
3086 u16 param0, u16 param1, u16 param2,
3087 u16 param3, u16 param4)
3088{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003089 u16 curCmd = 0;
3090 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003091 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003092 u16 scExec = 0;
3093 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003094
3095 status = Read16_0(state, OFDM_SC_COMM_EXEC__A, &scExec);
3096 if (scExec != 1) {
3097 /* SC is not running */
3098 return -1;
3099 }
3100
3101 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003102 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003103 do {
3104 msleep(1);
3105 status = Read16_0(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
3106 retryCnt++;
3107 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
3108 if (retryCnt >= DRXK_MAX_RETRIES)
3109 return -1;
3110 /* Write sub-command */
3111 switch (cmd) {
3112 /* All commands using sub-cmd */
3113 case OFDM_SC_RA_RAM_CMD_PROC_START:
3114 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3115 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003116 status =
3117 Write16_0(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003118 break;
3119 default:
3120 /* Do nothing */
3121 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003122 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003123
3124 /* Write needed parameters and the command */
3125 switch (cmd) {
3126 /* All commands using 5 parameters */
3127 /* All commands using 4 parameters */
3128 /* All commands using 3 parameters */
3129 /* All commands using 2 parameters */
3130 case OFDM_SC_RA_RAM_CMD_PROC_START:
3131 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3132 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003133 status =
3134 Write16_0(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003135 /* All commands using 1 parameters */
3136 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3137 case OFDM_SC_RA_RAM_CMD_USER_IO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003138 status =
3139 Write16_0(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003140 /* All commands using 0 parameters */
3141 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3142 case OFDM_SC_RA_RAM_CMD_NULL:
3143 /* Write command */
3144 status = Write16_0(state, OFDM_SC_RA_RAM_CMD__A, cmd);
3145 break;
3146 default:
3147 /* Unknown command */
3148 return -EINVAL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003149 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003150
3151 /* Wait until sc is ready processing command */
3152 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003153 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003154 msleep(1);
3155 status = Read16_0(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
3156 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003157 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003158 if (retryCnt >= DRXK_MAX_RETRIES)
3159 return -1;
3160
3161 /* Check for illegal cmd */
3162 status = Read16_0(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003163 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003164 /* illegal command */
3165 return -EINVAL;
3166 }
3167
3168 /* Retreive results parameters from SC */
3169 switch (cmd) {
3170 /* All commands yielding 5 results */
3171 /* All commands yielding 4 results */
3172 /* All commands yielding 3 results */
3173 /* All commands yielding 2 results */
3174 /* All commands yielding 1 result */
3175 case OFDM_SC_RA_RAM_CMD_USER_IO:
3176 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003177 status =
3178 Read16_0(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003179 /* All commands yielding 0 results */
3180 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3181 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3182 case OFDM_SC_RA_RAM_CMD_PROC_START:
3183 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3184 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3185 case OFDM_SC_RA_RAM_CMD_NULL:
3186 break;
3187 default:
3188 /* Unknown command */
3189 return -EINVAL;
3190 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003191 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003192 return status;
3193}
3194
Oliver Endrissebc7de22011-07-03 13:49:44 -03003195static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003196{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003197 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003198 int status;
3199
3200 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003201 status = CtrlPowerMode(state, &powerMode);
3202 if (status < 0)
3203 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003204 } while (0);
3205 return status;
3206}
3207
Oliver Endrissebc7de22011-07-03 13:49:44 -03003208static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003209{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003210 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003211
3212 if (*enabled == true)
3213 status = Write16_0(state, IQM_CF_BYPASSDET__A, 0);
3214 else
3215 status = Write16_0(state, IQM_CF_BYPASSDET__A, 1);
3216
3217 return status;
3218}
3219
3220#define DEFAULT_FR_THRES_8K 4000
3221static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3222{
3223
3224 int status;
3225
3226 if (*enabled == true) {
3227 /* write mask to 1 */
3228 status = Write16_0(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
3229 DEFAULT_FR_THRES_8K);
3230 } else {
3231 /* write mask to 0 */
3232 status = Write16_0(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
3233 }
3234
3235 return status;
3236}
3237
3238static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3239 struct DRXKCfgDvbtEchoThres_t *echoThres)
3240{
3241 u16 data = 0;
3242 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003243
3244 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003245 status = Read16_0(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3246 if (status < 0)
3247 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003248
Oliver Endrissebc7de22011-07-03 13:49:44 -03003249 switch (echoThres->fftMode) {
3250 case DRX_FFTMODE_2K:
3251 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3252 data |=
3253 ((echoThres->threshold <<
3254 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3255 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3256 break;
3257 case DRX_FFTMODE_8K:
3258 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3259 data |=
3260 ((echoThres->threshold <<
3261 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3262 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3263 break;
3264 default:
3265 return -1;
3266 break;
3267 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003268
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003269 status = Write16_0(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3270 if (status < 0)
3271 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003272 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003273
Oliver Endrissebc7de22011-07-03 13:49:44 -03003274 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003275}
3276
3277static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003278 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003279{
3280 int status;
3281
3282 switch (*speed) {
3283 case DRXK_DVBT_SQI_SPEED_FAST:
3284 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3285 case DRXK_DVBT_SQI_SPEED_SLOW:
3286 break;
3287 default:
3288 return -EINVAL;
3289 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03003290 status = Write16_0(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
3291 (u16) *speed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003292 return status;
3293}
3294
3295/*============================================================================*/
3296
3297/**
3298* \brief Activate DVBT specific presets
3299* \param demod instance of demodulator.
3300* \return DRXStatus_t.
3301*
3302* Called in DVBTSetStandard
3303*
3304*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003305static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003306{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003307 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003308
Oliver Endrissebc7de22011-07-03 13:49:44 -03003309 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3310 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003311
Oliver Endrissebc7de22011-07-03 13:49:44 -03003312 do {
3313 bool setincenable = false;
3314 bool setfrenable = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003315 status = DVBTCtrlSetIncEnable(state, &setincenable);
3316 if (status < 0)
3317 break;
3318 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3319 if (status < 0)
3320 break;
3321 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3322 if (status < 0)
3323 break;
3324 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3325 if (status < 0)
3326 break;
3327 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3328 if (status < 0)
3329 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003330 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003331
Oliver Endrissebc7de22011-07-03 13:49:44 -03003332 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003333}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003334
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003335/*============================================================================*/
3336
3337/**
3338* \brief Initialize channelswitch-independent settings for DVBT.
3339* \param demod instance of demodulator.
3340* \return DRXStatus_t.
3341*
3342* For ROM code channel filter taps are loaded from the bootloader. For microcode
3343* the DVB-T taps from the drxk_filters.h are used.
3344*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003345static int SetDVBTStandard(struct drxk_state *state,
3346 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003347{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003348 u16 cmdResult = 0;
3349 u16 data = 0;
3350 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003351
3352 PowerUpDVBT(state);
3353
3354 do {
3355 /* added antenna switch */
3356 SwitchAntennaToDVBT(state);
3357 /* send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003358 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
3359 if (status < 0)
3360 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003361
3362 /* send OFDM setenv command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003363 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3364 if (status < 0)
3365 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003366
3367 /* reset datapath for OFDM, processors first */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003368 status = Write16_0(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3369 if (status < 0)
3370 break;
3371 status = Write16_0(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3372 if (status < 0)
3373 break;
3374 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3375 if (status < 0)
3376 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003377
3378 /* IQM setup */
3379 /* synchronize on ofdstate->m_festart */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003380 status = Write16_0(state, IQM_AF_UPD_SEL__A, 1);
3381 if (status < 0)
3382 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003383 /* window size for clipping ADC detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003384 status = Write16_0(state, IQM_AF_CLP_LEN__A, 0);
3385 if (status < 0)
3386 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003387 /* window size for for sense pre-SAW detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003388 status = Write16_0(state, IQM_AF_SNS_LEN__A, 0);
3389 if (status < 0)
3390 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003391 /* sense threshold for sense pre-SAW detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003392 status = Write16_0(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3393 if (status < 0)
3394 break;
3395 status = SetIqmAf(state, true);
3396 if (status < 0)
3397 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003398
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003399 status = Write16_0(state, IQM_AF_AGC_RF__A, 0);
3400 if (status < 0)
3401 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003402
3403 /* Impulse noise cruncher setup */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003404 status = Write16_0(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3405 if (status < 0)
3406 break;
3407 status = Write16_0(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3408 if (status < 0)
3409 break;
3410 status = Write16_0(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3411 if (status < 0)
3412 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003413
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003414 status = Write16_0(state, IQM_RC_STRETCH__A, 16);
3415 if (status < 0)
3416 break;
3417 status = Write16_0(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3418 if (status < 0)
3419 break;
3420 status = Write16_0(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3421 if (status < 0)
3422 break;
3423 status = Write16_0(state, IQM_CF_SCALE__A, 1600);
3424 if (status < 0)
3425 break;
3426 status = Write16_0(state, IQM_CF_SCALE_SH__A, 0);
3427 if (status < 0)
3428 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003429
3430 /* virtual clipping threshold for clipping ADC detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003431 status = Write16_0(state, IQM_AF_CLP_TH__A, 448);
3432 if (status < 0)
3433 break;
3434 status = Write16_0(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3435 if (status < 0)
3436 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003437
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003438 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3439 if (status < 0)
3440 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003441
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003442 status = Write16_0(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3443 if (status < 0)
3444 break;
3445 status = Write16_0(state, IQM_CF_POW_MEAS_LEN__A, 2);
3446 if (status < 0)
3447 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003448 /* enable power measurement interrupt */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003449 status = Write16_0(state, IQM_CF_COMM_INT_MSK__A, 1);
3450 if (status < 0)
3451 break;
3452 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3453 if (status < 0)
3454 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003455
3456 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003457 status = ADCSynchronization(state);
3458 if (status < 0)
3459 break;
3460 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3461 if (status < 0)
3462 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003463
3464 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003465 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3466 if (status < 0)
3467 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003468
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003469 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3470 if (status < 0)
3471 break;
3472 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3473 if (status < 0)
3474 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003475
3476 /* Set Noise Estimation notch width and enable DC fix */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003477 status = Read16_0(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3478 if (status < 0)
3479 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003480 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003481 status = Write16_0(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3482 if (status < 0)
3483 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003484
3485 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003486 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3487 if (status < 0)
3488 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003489
Oliver Endrissebc7de22011-07-03 13:49:44 -03003490 if (!state->m_DRXK_A3_ROM_CODE) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003491 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003492 status = Write16_0(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3493 if (status < 0)
3494 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003495 }
3496
3497 /* OFDM_SC setup */
3498#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003499 status = Write16_0(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3500 if (status < 0)
3501 break;
3502 status = Write16_0(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3503 if (status < 0)
3504 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003505#endif
3506
3507 /* FEC setup */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003508 status = Write16_0(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3509 if (status < 0)
3510 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003511
3512
3513#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003514 status = Write16_0(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3515 if (status < 0)
3516 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003517#else
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003518 status = Write16_0(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3519 if (status < 0)
3520 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003521#endif
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003522 status = Write16_0(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3523 if (status < 0)
3524 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003525
3526 /* Setup MPEG bus */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003527 status = MPEGTSDtoSetup(state, OM_DVBT);
3528 if (status < 0)
3529 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003530 /* Set DVBT Presets */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003531 status = DVBTActivatePresets(state);
3532 if (status < 0)
3533 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003534
3535 } while (0);
3536
Oliver Endrissebc7de22011-07-03 13:49:44 -03003537 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003538 printk(KERN_ERR "drxk: %s status - %08x\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003539
3540 return status;
3541}
3542
3543/*============================================================================*/
3544/**
3545* \brief Start dvbt demodulating for channel.
3546* \param demod instance of demodulator.
3547* \return DRXStatus_t.
3548*/
3549static int DVBTStart(struct drxk_state *state)
3550{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003551 u16 param1;
3552 int status;
3553 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003554
Oliver Endrissebc7de22011-07-03 13:49:44 -03003555 /* Start correct processes to get in lock */
3556 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
3557 do {
3558 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003559 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3560 if (status < 0)
3561 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003562 /* Start FEC OC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003563 status = MPEGTSStart(state);
3564 if (status < 0)
3565 break;
3566 status = Write16_0(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3567 if (status < 0)
3568 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003569 } while (0);
3570 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003571}
3572
3573
3574/*============================================================================*/
3575
3576/**
3577* \brief Set up dvbt demodulator for channel.
3578* \param demod instance of demodulator.
3579* \return DRXStatus_t.
3580* // original DVBTSetChannel()
3581*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003582static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3583 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003584{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003585 u16 cmdResult = 0;
3586 u16 transmissionParams = 0;
3587 u16 operationMode = 0;
3588 u32 iqmRcRateOfs = 0;
3589 u32 bandwidth = 0;
3590 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003591 int status;
3592
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003593 /* printk(KERN_DEBUG "drxk: %s IF =%d, TFO = %d\n", __func__, IntermediateFreqkHz, tunerFreqOffset); */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003594 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003595 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3596 if (status < 0)
3597 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003598
3599 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003600 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3601 if (status < 0)
3602 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003603
3604 /* Stop processors */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003605 status = Write16_0(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3606 if (status < 0)
3607 break;
3608 status = Write16_0(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3609 if (status < 0)
3610 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003611
3612 /* Mandatory fix, always stop CP, required to set spl offset back to
3613 hardware default (is set to 0 by ucode during pilot detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003614 status = Write16_0(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3615 if (status < 0)
3616 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003617
3618 /*== Write channel settings to device =====================================*/
3619
3620 /* mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003621 switch (state->param.u.ofdm.transmission_mode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003622 case TRANSMISSION_MODE_AUTO:
3623 default:
3624 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3625 /* fall through , try first guess DRX_FFTMODE_8K */
3626 case TRANSMISSION_MODE_8K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003627 transmissionParams |=
3628 OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003629 break;
3630 case TRANSMISSION_MODE_2K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003631 transmissionParams |=
3632 OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003633 break;
3634 }
3635
3636 /* guard */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003637 switch (state->param.u.ofdm.guard_interval) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003638 default:
3639 case GUARD_INTERVAL_AUTO:
3640 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3641 /* fall through , try first guess DRX_GUARD_1DIV4 */
3642 case GUARD_INTERVAL_1_4:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003643 transmissionParams |=
3644 OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003645 break;
3646 case GUARD_INTERVAL_1_32:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003647 transmissionParams |=
3648 OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003649 break;
3650 case GUARD_INTERVAL_1_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003651 transmissionParams |=
3652 OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003653 break;
3654 case GUARD_INTERVAL_1_8:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003655 transmissionParams |=
3656 OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003657 break;
3658 }
3659
3660 /* hierarchy */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003661 switch (state->param.u.ofdm.hierarchy_information) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003662 case HIERARCHY_AUTO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003663 case HIERARCHY_NONE:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003664 default:
3665 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3666 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003667 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3668 /* break; */
3669 case HIERARCHY_1:
3670 transmissionParams |=
3671 OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003672 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003673 case HIERARCHY_2:
3674 transmissionParams |=
3675 OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003676 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003677 case HIERARCHY_4:
3678 transmissionParams |=
3679 OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003680 break;
3681 }
3682
3683
3684 /* constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003685 switch (state->param.u.ofdm.constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003686 case QAM_AUTO:
3687 default:
3688 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3689 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3690 case QAM_64:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003691 transmissionParams |=
3692 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003693 break;
3694 case QPSK:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003695 transmissionParams |=
3696 OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003697 break;
3698 case QAM_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003699 transmissionParams |=
3700 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003701 break;
3702 }
3703#if 0
Oliver Endrissebc7de22011-07-03 13:49:44 -03003704 /* No hierachical channels support in BDA */
3705 /* Priority (only for hierarchical channels) */
3706 switch (channel->priority) {
3707 case DRX_PRIORITY_LOW:
3708 transmissionParams |=
3709 OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3710 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3711 OFDM_EC_SB_PRIOR_LO);
3712 break;
3713 case DRX_PRIORITY_HIGH:
3714 transmissionParams |=
3715 OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3716 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3717 OFDM_EC_SB_PRIOR_HI));
3718 break;
3719 case DRX_PRIORITY_UNKNOWN: /* fall through */
3720 default:
3721 return DRX_STS_INVALID_ARG;
3722 break;
3723 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003724#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03003725 /* Set Priorty high */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003726 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003727 status = Write16_0(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3728 if (status < 0)
3729 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003730#endif
3731
3732 /* coderate */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003733 switch (state->param.u.ofdm.code_rate_HP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003734 case FEC_AUTO:
3735 default:
3736 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3737 /* fall through , try first guess DRX_CODERATE_2DIV3 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003738 case FEC_2_3:
3739 transmissionParams |=
3740 OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003741 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003742 case FEC_1_2:
3743 transmissionParams |=
3744 OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003745 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003746 case FEC_3_4:
3747 transmissionParams |=
3748 OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003749 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003750 case FEC_5_6:
3751 transmissionParams |=
3752 OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003753 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003754 case FEC_7_8:
3755 transmissionParams |=
3756 OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003757 break;
3758 }
3759
3760 /* SAW filter selection: normaly not necesarry, but if wanted
3761 the application can select a SAW filter via the driver by using UIOs */
3762 /* First determine real bandwidth (Hz) */
3763 /* Also set delay for impulse noise cruncher */
3764 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3765 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3766 functions */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003767 switch (state->param.u.ofdm.bandwidth) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003768 case BANDWIDTH_AUTO:
3769 case BANDWIDTH_8_MHZ:
3770 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003771 status = Write16_0(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
3772 if (status < 0)
3773 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003774 /* cochannel protection for PAL 8 MHz */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003775 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3776 if (status < 0)
3777 break;
3778 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3779 if (status < 0)
3780 break;
3781 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3782 if (status < 0)
3783 break;
3784 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3785 if (status < 0)
3786 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003787 break;
3788 case BANDWIDTH_7_MHZ:
3789 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003790 status = Write16_0(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3791 if (status < 0)
3792 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003793 /* cochannel protection for PAL 7 MHz */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003794 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3795 if (status < 0)
3796 break;
3797 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3798 if (status < 0)
3799 break;
3800 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3801 if (status < 0)
3802 break;
3803 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3804 if (status < 0)
3805 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003806 break;
3807 case BANDWIDTH_6_MHZ:
3808 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003809 status = Write16_0(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3810 if (status < 0)
3811 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003812 /* cochannel protection for NTSC 6 MHz */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003813 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3814 if (status < 0)
3815 break;
3816 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3817 if (status < 0)
3818 break;
3819 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3820 if (status < 0)
3821 break;
3822 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3823 if (status < 0)
3824 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003825 break;
Mauro Carvalho Chehabe16cede2011-07-03 18:18:14 -03003826 default:
3827 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003828 }
3829
Oliver Endrissebc7de22011-07-03 13:49:44 -03003830 if (iqmRcRateOfs == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003831 /* Now compute IQM_RC_RATE_OFS
3832 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3833 =>
3834 ((SysFreq / BandWidth) * (2^21)) - (2^23)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003835 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003836 /* (SysFreq / BandWidth) * (2^28) */
3837 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
3838 => assert(MAX(sysClk) < 16*MIN(bandwidth))
3839 => assert(109714272 > 48000000) = true so Frac 28 can be used */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003840 iqmRcRateOfs = Frac28a((u32)
3841 ((state->m_sysClockFreq *
3842 1000) / 3), bandwidth);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003843 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
3844 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003845 iqmRcRateOfs += 0x80L;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003846 iqmRcRateOfs = iqmRcRateOfs >> 7;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003847 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003848 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003849 }
3850
Oliver Endrissebc7de22011-07-03 13:49:44 -03003851 iqmRcRateOfs &=
3852 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
3853 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003854 status = Write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs, 0);
3855 if (status < 0)
3856 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003857
3858 /* Bandwidth setting done */
3859
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003860#if 0
3861 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
3862 if (status < 0)
3863 break;
3864#endif
3865 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
3866 if (status < 0)
3867 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003868
3869 /*== Start SC, write channel settings to SC ===============================*/
3870
3871 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003872 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3873 if (status < 0)
3874 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003875
3876 /* Enable SC after setting all other parameters */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003877 status = Write16_0(state, OFDM_SC_COMM_STATE__A, 0);
3878 if (status < 0)
3879 break;
3880 status = Write16_0(state, OFDM_SC_COMM_EXEC__A, 1);
3881 if (status < 0)
3882 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003883
3884
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003885 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
3886 if (status < 0)
3887 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003888
3889 /* Write SC parameter registers, set all AUTO flags in operation mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003890 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
3891 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
3892 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
3893 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
3894 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
3895 status =
3896 DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
3897 0, transmissionParams, param1, 0, 0, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003898 if (!state->m_DRXK_A3_ROM_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003899 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
3900 if (status < 0)
3901 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003902
Oliver Endrissebc7de22011-07-03 13:49:44 -03003903 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003904
3905 return status;
3906}
3907
3908
3909/*============================================================================*/
3910
3911/**
3912* \brief Retreive lock status .
3913* \param demod Pointer to demodulator instance.
3914* \param lockStat Pointer to lock status structure.
3915* \return DRXStatus_t.
3916*
3917*/
3918static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
3919{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003920 int status;
3921 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
3922 OFDM_SC_RA_RAM_LOCK_FEC__M);
3923 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
3924 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003925
Oliver Endrissebc7de22011-07-03 13:49:44 -03003926 u16 ScRaRamLock = 0;
3927 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003928
Oliver Endrissebc7de22011-07-03 13:49:44 -03003929 /* driver 0.9.0 */
3930 /* Check if SC is running */
3931 status = Read16_0(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
3932 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP) {
3933 /* SC not active; return DRX_NOT_LOCKED */
3934 *pLockStatus = NOT_LOCKED;
3935 return status;
3936 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003937
Oliver Endrissebc7de22011-07-03 13:49:44 -03003938 status = Read16_0(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003939
Oliver Endrissebc7de22011-07-03 13:49:44 -03003940 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
3941 *pLockStatus = MPEG_LOCK;
3942 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
3943 *pLockStatus = FEC_LOCK;
3944 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
3945 *pLockStatus = DEMOD_LOCK;
3946 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
3947 *pLockStatus = NEVER_LOCK;
3948 else
3949 *pLockStatus = NOT_LOCKED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003950
Oliver Endrissebc7de22011-07-03 13:49:44 -03003951 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003952}
3953
Oliver Endrissebc7de22011-07-03 13:49:44 -03003954static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003955{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003956 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
3957 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003958
Oliver Endrissebc7de22011-07-03 13:49:44 -03003959 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003960 status = CtrlPowerMode(state, &powerMode);
3961 if (status < 0)
3962 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003963
Oliver Endrissebc7de22011-07-03 13:49:44 -03003964 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003965
Oliver Endrissebc7de22011-07-03 13:49:44 -03003966 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003967}
3968
3969
Oliver Endrissebc7de22011-07-03 13:49:44 -03003970/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003971static int PowerDownQAM(struct drxk_state *state)
3972{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003973 u16 data = 0;
3974 u16 cmdResult;
3975 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003976
Oliver Endrissebc7de22011-07-03 13:49:44 -03003977 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003978 status = Read16_0(state, SCU_COMM_EXEC__A, &data);
3979 if (status < 0)
3980 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003981 if (data == SCU_COMM_EXEC_ACTIVE) {
3982 /*
3983 STOP demodulator
3984 QAM and HW blocks
3985 */
3986 /* stop all comstate->m_exec */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003987 status = Write16_0(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
3988 if (status < 0)
3989 break;
3990 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3991 if (status < 0)
3992 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003993 }
3994 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003995 status = SetIqmAf(state, false);
3996 if (status < 0)
3997 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003998 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003999
Oliver Endrissebc7de22011-07-03 13:49:44 -03004000 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004001}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004002
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004003/*============================================================================*/
4004
4005/**
4006* \brief Setup of the QAM Measurement intervals for signal quality
4007* \param demod instance of demod.
4008* \param constellation current constellation.
4009* \return DRXStatus_t.
4010*
4011* NOTE:
4012* Take into account that for certain settings the errorcounters can overflow.
4013* The implementation does not check this.
4014*
4015*/
4016static int SetQAMMeasurement(struct drxk_state *state,
4017 enum EDrxkConstellation constellation,
4018 u32 symbolRate)
4019{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004020 u32 fecBitsDesired = 0; /* BER accounting period */
4021 u32 fecRsPeriodTotal = 0; /* Total period */
4022 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4023 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004024 int status = 0;
4025
Oliver Endrissebc7de22011-07-03 13:49:44 -03004026 fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004027
4028 do {
4029
4030 /* fecBitsDesired = symbolRate [kHz] *
4031 FrameLenght [ms] *
4032 (constellation + 1) *
4033 SyncLoss (== 1) *
4034 ViterbiLoss (==1)
Oliver Endrissebc7de22011-07-03 13:49:44 -03004035 */
4036 switch (constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004037 case DRX_CONSTELLATION_QAM16:
4038 fecBitsDesired = 4 * symbolRate;
4039 break;
4040 case DRX_CONSTELLATION_QAM32:
4041 fecBitsDesired = 5 * symbolRate;
4042 break;
4043 case DRX_CONSTELLATION_QAM64:
4044 fecBitsDesired = 6 * symbolRate;
4045 break;
4046 case DRX_CONSTELLATION_QAM128:
4047 fecBitsDesired = 7 * symbolRate;
4048 break;
4049 case DRX_CONSTELLATION_QAM256:
4050 fecBitsDesired = 8 * symbolRate;
4051 break;
4052 default:
4053 status = -EINVAL;
4054 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004055 status = status;
4056 if (status < 0)
4057 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004058
Oliver Endrissebc7de22011-07-03 13:49:44 -03004059 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4060 fecBitsDesired *= 500; /* meas. period [ms] */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004061
4062 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4063 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004064 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004065
4066 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4067 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4068 if (fecRsPrescale == 0) {
4069 /* Divide by zero (though impossible) */
4070 status = -1;
4071 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004072 status = status;
4073 if (status < 0)
4074 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004075 fecRsPeriod =
4076 ((u16) fecRsPeriodTotal +
4077 (fecRsPrescale >> 1)) / fecRsPrescale;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004078
4079 /* write corresponding registers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004080 status = Write16_0(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4081 if (status < 0)
4082 break;
4083 status = Write16_0(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4084 if (status < 0)
4085 break;
4086 status = Write16_0(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4087 if (status < 0)
4088 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004089
4090 } while (0);
4091
Oliver Endrissebc7de22011-07-03 13:49:44 -03004092 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03004093 printk(KERN_ERR "drxk: %s: status - %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004094
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004095 return status;
4096}
4097
Oliver Endrissebc7de22011-07-03 13:49:44 -03004098static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004099{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004100 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004101
Oliver Endrissebc7de22011-07-03 13:49:44 -03004102 do {
4103 /* QAM Equalizer Setup */
4104 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004105 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4106 if (status < 0)
4107 break;
4108 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4109 if (status < 0)
4110 break;
4111 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4112 if (status < 0)
4113 break;
4114 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4115 if (status < 0)
4116 break;
4117 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4118 if (status < 0)
4119 break;
4120 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4121 if (status < 0)
4122 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004123 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004124 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 2);
4125 if (status < 0)
4126 break;
4127 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 2);
4128 if (status < 0)
4129 break;
4130 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 2);
4131 if (status < 0)
4132 break;
4133 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 2);
4134 if (status < 0)
4135 break;
4136 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 2);
4137 if (status < 0)
4138 break;
4139 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4140 if (status < 0)
4141 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004142
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004143 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 5);
4144 if (status < 0)
4145 break;
4146 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 4);
4147 if (status < 0)
4148 break;
4149 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4150 if (status < 0)
4151 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004152
Oliver Endrissebc7de22011-07-03 13:49:44 -03004153 /* QAM Slicer Settings */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004154 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4155 if (status < 0)
4156 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004157
Oliver Endrissebc7de22011-07-03 13:49:44 -03004158 /* QAM Loop Controller Coeficients */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004159 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4160 if (status < 0)
4161 break;
4162 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4163 if (status < 0)
4164 break;
4165 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4166 if (status < 0)
4167 break;
4168 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4169 if (status < 0)
4170 break;
4171 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4172 if (status < 0)
4173 break;
4174 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4175 if (status < 0)
4176 break;
4177 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4178 if (status < 0)
4179 break;
4180 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4181 if (status < 0)
4182 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004183
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004184 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4185 if (status < 0)
4186 break;
4187 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4188 if (status < 0)
4189 break;
4190 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4191 if (status < 0)
4192 break;
4193 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4194 if (status < 0)
4195 break;
4196 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4197 if (status < 0)
4198 break;
4199 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4200 if (status < 0)
4201 break;
4202 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4203 if (status < 0)
4204 break;
4205 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4206 if (status < 0)
4207 break;
4208 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4209 if (status < 0)
4210 break;
4211 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4212 if (status < 0)
4213 break;
4214 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4215 if (status < 0)
4216 break;
4217 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4218 if (status < 0)
4219 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004220
4221
Oliver Endrissebc7de22011-07-03 13:49:44 -03004222 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004223
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004224 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4225 if (status < 0)
4226 break;
4227 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4228 if (status < 0)
4229 break;
4230 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4231 if (status < 0)
4232 break;
4233 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4234 if (status < 0)
4235 break;
4236 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4237 if (status < 0)
4238 break;
4239 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4240 if (status < 0)
4241 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004242
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004243 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4244 if (status < 0)
4245 break;
4246 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4247 if (status < 0)
4248 break;
4249 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4250 if (status < 0)
4251 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004252
4253
Oliver Endrissebc7de22011-07-03 13:49:44 -03004254 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004255
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004256 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4257 if (status < 0)
4258 break;
4259 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4260 if (status < 0)
4261 break;
4262 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4263 if (status < 0)
4264 break;
4265 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4266 if (status < 0)
4267 break;
4268 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4269 if (status < 0)
4270 break;
4271 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4272 if (status < 0)
4273 break;
4274 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4275 if (status < 0)
4276 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004277 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004278
Oliver Endrissebc7de22011-07-03 13:49:44 -03004279 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004280}
4281
4282/*============================================================================*/
4283
4284/**
4285* \brief QAM32 specific setup
4286* \param demod instance of demod.
4287* \return DRXStatus_t.
4288*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004289static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004290{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004291 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004292
Oliver Endrissebc7de22011-07-03 13:49:44 -03004293 do {
4294 /* QAM Equalizer Setup */
4295 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004296 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4297 if (status < 0)
4298 break;
4299 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4300 if (status < 0)
4301 break;
4302 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4303 if (status < 0)
4304 break;
4305 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4306 if (status < 0)
4307 break;
4308 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4309 if (status < 0)
4310 break;
4311 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4312 if (status < 0)
4313 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004314
Oliver Endrissebc7de22011-07-03 13:49:44 -03004315 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004316 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 3);
4317 if (status < 0)
4318 break;
4319 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 3);
4320 if (status < 0)
4321 break;
4322 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 3);
4323 if (status < 0)
4324 break;
4325 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 3);
4326 if (status < 0)
4327 break;
4328 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 3);
4329 if (status < 0)
4330 break;
4331 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4332 if (status < 0)
4333 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004334
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004335 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 6);
4336 if (status < 0)
4337 break;
4338 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 5);
4339 if (status < 0)
4340 break;
4341 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4342 if (status < 0)
4343 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004344
Oliver Endrissebc7de22011-07-03 13:49:44 -03004345 /* QAM Slicer Settings */
4346
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004347 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4348 if (status < 0)
4349 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004350
4351
Oliver Endrissebc7de22011-07-03 13:49:44 -03004352 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004353
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004354 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4355 if (status < 0)
4356 break;
4357 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4358 if (status < 0)
4359 break;
4360 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4361 if (status < 0)
4362 break;
4363 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4364 if (status < 0)
4365 break;
4366 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4367 if (status < 0)
4368 break;
4369 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4370 if (status < 0)
4371 break;
4372 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4373 if (status < 0)
4374 break;
4375 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4376 if (status < 0)
4377 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004378
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004379 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4380 if (status < 0)
4381 break;
4382 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4383 if (status < 0)
4384 break;
4385 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4386 if (status < 0)
4387 break;
4388 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4389 if (status < 0)
4390 break;
4391 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4392 if (status < 0)
4393 break;
4394 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4395 if (status < 0)
4396 break;
4397 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4398 if (status < 0)
4399 break;
4400 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4401 if (status < 0)
4402 break;
4403 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4404 if (status < 0)
4405 break;
4406 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4407 if (status < 0)
4408 break;
4409 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4410 if (status < 0)
4411 break;
4412 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4413 if (status < 0)
4414 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004415
4416
Oliver Endrissebc7de22011-07-03 13:49:44 -03004417 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004418
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004419 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4420 if (status < 0)
4421 break;
4422 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4423 if (status < 0)
4424 break;
4425 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4426 if (status < 0)
4427 break;
4428 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4429 if (status < 0)
4430 break;
4431 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4432 if (status < 0)
4433 break;
4434 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4435 if (status < 0)
4436 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004437
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004438 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4439 if (status < 0)
4440 break;
4441 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4442 if (status < 0)
4443 break;
4444 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4445 if (status < 0)
4446 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004447
4448
Oliver Endrissebc7de22011-07-03 13:49:44 -03004449 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004450
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004451 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4452 if (status < 0)
4453 break;
4454 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4455 if (status < 0)
4456 break;
4457 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4458 if (status < 0)
4459 break;
4460 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4461 if (status < 0)
4462 break;
4463 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4464 if (status < 0)
4465 break;
4466 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4467 if (status < 0)
4468 break;
4469 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4470 if (status < 0)
4471 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004472 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004473
Oliver Endrissebc7de22011-07-03 13:49:44 -03004474 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004475}
4476
4477/*============================================================================*/
4478
4479/**
4480* \brief QAM64 specific setup
4481* \param demod instance of demod.
4482* \return DRXStatus_t.
4483*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004484static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004485{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004486 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004487
Oliver Endrissebc7de22011-07-03 13:49:44 -03004488 do {
4489 /* QAM Equalizer Setup */
4490 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004491 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4492 if (status < 0)
4493 break;
4494 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4495 if (status < 0)
4496 break;
4497 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4498 if (status < 0)
4499 break;
4500 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4501 if (status < 0)
4502 break;
4503 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4504 if (status < 0)
4505 break;
4506 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4507 if (status < 0)
4508 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004509
Oliver Endrissebc7de22011-07-03 13:49:44 -03004510 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004511 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 4);
4512 if (status < 0)
4513 break;
4514 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 4);
4515 if (status < 0)
4516 break;
4517 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 4);
4518 if (status < 0)
4519 break;
4520 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 4);
4521 if (status < 0)
4522 break;
4523 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 3);
4524 if (status < 0)
4525 break;
4526 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4527 if (status < 0)
4528 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004529
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004530 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 5);
4531 if (status < 0)
4532 break;
4533 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 4);
4534 if (status < 0)
4535 break;
4536 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4537 if (status < 0)
4538 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004539
4540 /* QAM Slicer Settings */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004541 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4542 if (status < 0)
4543 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004544
4545
Oliver Endrissebc7de22011-07-03 13:49:44 -03004546 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004547
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004548 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4549 if (status < 0)
4550 break;
4551 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4552 if (status < 0)
4553 break;
4554 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4555 if (status < 0)
4556 break;
4557 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4558 if (status < 0)
4559 break;
4560 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4561 if (status < 0)
4562 break;
4563 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4564 if (status < 0)
4565 break;
4566 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4567 if (status < 0)
4568 break;
4569 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4570 if (status < 0)
4571 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004572
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004573 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4574 if (status < 0)
4575 break;
4576 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4577 if (status < 0)
4578 break;
4579 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4580 if (status < 0)
4581 break;
4582 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4583 if (status < 0)
4584 break;
4585 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4586 if (status < 0)
4587 break;
4588 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4589 if (status < 0)
4590 break;
4591 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4592 if (status < 0)
4593 break;
4594 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4595 if (status < 0)
4596 break;
4597 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4598 if (status < 0)
4599 break;
4600 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4601 if (status < 0)
4602 break;
4603 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4604 if (status < 0)
4605 break;
4606 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4607 if (status < 0)
4608 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004609
4610
Oliver Endrissebc7de22011-07-03 13:49:44 -03004611 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004612
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004613 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4614 if (status < 0)
4615 break;
4616 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4617 if (status < 0)
4618 break;
4619 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4620 if (status < 0)
4621 break;
4622 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4623 if (status < 0)
4624 break;
4625 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4626 if (status < 0)
4627 break;
4628 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4629 if (status < 0)
4630 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004631
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004632 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4633 if (status < 0)
4634 break;
4635 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4636 if (status < 0)
4637 break;
4638 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4639 if (status < 0)
4640 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004641
4642
Oliver Endrissebc7de22011-07-03 13:49:44 -03004643 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004644
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004645 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4646 if (status < 0)
4647 break;
4648 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4649 if (status < 0)
4650 break;
4651 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4652 if (status < 0)
4653 break;
4654 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4655 if (status < 0)
4656 break;
4657 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4658 if (status < 0)
4659 break;
4660 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4661 if (status < 0)
4662 break;
4663 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4664 if (status < 0)
4665 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004666 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004667
Oliver Endrissebc7de22011-07-03 13:49:44 -03004668 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004669}
4670
4671/*============================================================================*/
4672
4673/**
4674* \brief QAM128 specific setup
4675* \param demod: instance of demod.
4676* \return DRXStatus_t.
4677*/
4678static int SetQAM128(struct drxk_state *state)
4679{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004680 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004681
Oliver Endrissebc7de22011-07-03 13:49:44 -03004682 do {
4683 /* QAM Equalizer Setup */
4684 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004685 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4686 if (status < 0)
4687 break;
4688 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4689 if (status < 0)
4690 break;
4691 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4692 if (status < 0)
4693 break;
4694 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4695 if (status < 0)
4696 break;
4697 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4698 if (status < 0)
4699 break;
4700 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4701 if (status < 0)
4702 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004703
Oliver Endrissebc7de22011-07-03 13:49:44 -03004704 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004705 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 6);
4706 if (status < 0)
4707 break;
4708 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 6);
4709 if (status < 0)
4710 break;
4711 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 6);
4712 if (status < 0)
4713 break;
4714 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 6);
4715 if (status < 0)
4716 break;
4717 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 5);
4718 if (status < 0)
4719 break;
4720 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4721 if (status < 0)
4722 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004723
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004724 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 6);
4725 if (status < 0)
4726 break;
4727 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 5);
4728 if (status < 0)
4729 break;
4730 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4731 if (status < 0)
4732 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004733
4734
Oliver Endrissebc7de22011-07-03 13:49:44 -03004735 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004736
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004737 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4738 if (status < 0)
4739 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004740
4741
Oliver Endrissebc7de22011-07-03 13:49:44 -03004742 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004743
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004744 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4745 if (status < 0)
4746 break;
4747 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4748 if (status < 0)
4749 break;
4750 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4751 if (status < 0)
4752 break;
4753 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4754 if (status < 0)
4755 break;
4756 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4757 if (status < 0)
4758 break;
4759 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4760 if (status < 0)
4761 break;
4762 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4763 if (status < 0)
4764 break;
4765 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4766 if (status < 0)
4767 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004768
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004769 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4770 if (status < 0)
4771 break;
4772 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4773 if (status < 0)
4774 break;
4775 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4776 if (status < 0)
4777 break;
4778 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4779 if (status < 0)
4780 break;
4781 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4782 if (status < 0)
4783 break;
4784 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4785 if (status < 0)
4786 break;
4787 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4788 if (status < 0)
4789 break;
4790 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4791 if (status < 0)
4792 break;
4793 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4794 if (status < 0)
4795 break;
4796 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4797 if (status < 0)
4798 break;
4799 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4800 if (status < 0)
4801 break;
4802 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4803 if (status < 0)
4804 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004805
4806
Oliver Endrissebc7de22011-07-03 13:49:44 -03004807 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004808
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004809 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4810 if (status < 0)
4811 break;
4812 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4813 if (status < 0)
4814 break;
4815 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4816 if (status < 0)
4817 break;
4818 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4819 if (status < 0)
4820 break;
4821 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4822 if (status < 0)
4823 break;
4824 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4825 if (status < 0)
4826 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004827
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004828 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4829 if (status < 0)
4830 break;
4831 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
4832 if (status < 0)
4833 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004834
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004835 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
4836 if (status < 0)
4837 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004838
Oliver Endrissebc7de22011-07-03 13:49:44 -03004839 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004840
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004841 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
4842 if (status < 0)
4843 break;
4844 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
4845 if (status < 0)
4846 break;
4847 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
4848 if (status < 0)
4849 break;
4850 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
4851 if (status < 0)
4852 break;
4853 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
4854 if (status < 0)
4855 break;
4856 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
4857 if (status < 0)
4858 break;
4859 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
4860 if (status < 0)
4861 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004862 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004863
Oliver Endrissebc7de22011-07-03 13:49:44 -03004864 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004865}
4866
4867/*============================================================================*/
4868
4869/**
4870* \brief QAM256 specific setup
4871* \param demod: instance of demod.
4872* \return DRXStatus_t.
4873*/
4874static int SetQAM256(struct drxk_state *state)
4875{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004876 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004877
Oliver Endrissebc7de22011-07-03 13:49:44 -03004878 do {
4879 /* QAM Equalizer Setup */
4880 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004881 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
4882 if (status < 0)
4883 break;
4884 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
4885 if (status < 0)
4886 break;
4887 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
4888 if (status < 0)
4889 break;
4890 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
4891 if (status < 0)
4892 break;
4893 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
4894 if (status < 0)
4895 break;
4896 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
4897 if (status < 0)
4898 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004899
Oliver Endrissebc7de22011-07-03 13:49:44 -03004900 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004901 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 8);
4902 if (status < 0)
4903 break;
4904 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 8);
4905 if (status < 0)
4906 break;
4907 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 8);
4908 if (status < 0)
4909 break;
4910 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 8);
4911 if (status < 0)
4912 break;
4913 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 6);
4914 if (status < 0)
4915 break;
4916 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4917 if (status < 0)
4918 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004919
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004920 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 5);
4921 if (status < 0)
4922 break;
4923 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 4);
4924 if (status < 0)
4925 break;
4926 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4927 if (status < 0)
4928 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004929
Oliver Endrissebc7de22011-07-03 13:49:44 -03004930 /* QAM Slicer Settings */
4931
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004932 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
4933 if (status < 0)
4934 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004935
4936
Oliver Endrissebc7de22011-07-03 13:49:44 -03004937 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004938
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004939 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4940 if (status < 0)
4941 break;
4942 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4943 if (status < 0)
4944 break;
4945 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4946 if (status < 0)
4947 break;
4948 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4949 if (status < 0)
4950 break;
4951 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4952 if (status < 0)
4953 break;
4954 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4955 if (status < 0)
4956 break;
4957 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4958 if (status < 0)
4959 break;
4960 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4961 if (status < 0)
4962 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004963
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004964 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4965 if (status < 0)
4966 break;
4967 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
4968 if (status < 0)
4969 break;
4970 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
4971 if (status < 0)
4972 break;
4973 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4974 if (status < 0)
4975 break;
4976 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
4977 if (status < 0)
4978 break;
4979 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
4980 if (status < 0)
4981 break;
4982 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4983 if (status < 0)
4984 break;
4985 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4986 if (status < 0)
4987 break;
4988 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4989 if (status < 0)
4990 break;
4991 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4992 if (status < 0)
4993 break;
4994 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4995 if (status < 0)
4996 break;
4997 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4998 if (status < 0)
4999 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005000
5001
Oliver Endrissebc7de22011-07-03 13:49:44 -03005002 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005003
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005004 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5005 if (status < 0)
5006 break;
5007 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5008 if (status < 0)
5009 break;
5010 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5011 if (status < 0)
5012 break;
5013 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5014 if (status < 0)
5015 break;
5016 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5017 if (status < 0)
5018 break;
5019 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5020 if (status < 0)
5021 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005022
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005023 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5024 if (status < 0)
5025 break;
5026 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5027 if (status < 0)
5028 break;
5029 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5030 if (status < 0)
5031 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005032
5033
Oliver Endrissebc7de22011-07-03 13:49:44 -03005034 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005035
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005036 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5037 if (status < 0)
5038 break;
5039 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5040 if (status < 0)
5041 break;
5042 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5043 if (status < 0)
5044 break;
5045 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5046 if (status < 0)
5047 break;
5048 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5049 if (status < 0)
5050 break;
5051 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5052 if (status < 0)
5053 break;
5054 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5055 if (status < 0)
5056 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005057 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005058
Oliver Endrissebc7de22011-07-03 13:49:44 -03005059 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005060}
5061
5062
5063/*============================================================================*/
5064/**
5065* \brief Reset QAM block.
5066* \param demod: instance of demod.
5067* \param channel: pointer to channel data.
5068* \return DRXStatus_t.
5069*/
5070static int QAMResetQAM(struct drxk_state *state)
5071{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005072 int status;
5073 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005074
Oliver Endrissebc7de22011-07-03 13:49:44 -03005075 do {
5076 /* Stop QAM comstate->m_exec */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005077 status = Write16_0(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5078 if (status < 0)
5079 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005080
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005081 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5082 if (status < 0)
5083 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005084 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005085
Oliver Endrissebc7de22011-07-03 13:49:44 -03005086 /* All done, all OK */
5087 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005088}
5089
5090/*============================================================================*/
5091
5092/**
5093* \brief Set QAM symbolrate.
5094* \param demod: instance of demod.
5095* \param channel: pointer to channel data.
5096* \return DRXStatus_t.
5097*/
5098static int QAMSetSymbolrate(struct drxk_state *state)
5099{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005100 u32 adcFrequency = 0;
5101 u32 symbFreq = 0;
5102 u32 iqmRcRate = 0;
5103 u16 ratesel = 0;
5104 u32 lcSymbRate = 0;
5105 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005106
Oliver Endrissebc7de22011-07-03 13:49:44 -03005107 do {
5108 /* Select & calculate correct IQM rate */
5109 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5110 ratesel = 0;
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005111 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005112 if (state->param.u.qam.symbol_rate <= 1188750)
5113 ratesel = 3;
5114 else if (state->param.u.qam.symbol_rate <= 2377500)
5115 ratesel = 2;
5116 else if (state->param.u.qam.symbol_rate <= 4755000)
5117 ratesel = 1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005118 status = Write16_0(state, IQM_FD_RATESEL__A, ratesel);
5119 if (status < 0)
5120 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005121
Oliver Endrissebc7de22011-07-03 13:49:44 -03005122 /*
5123 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5124 */
5125 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5126 if (symbFreq == 0) {
5127 /* Divide by zero */
5128 return -1;
5129 }
5130 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5131 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5132 (1 << 23);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005133 status = Write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate, 0);
5134 if (status < 0)
5135 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005136 state->m_iqmRcRate = iqmRcRate;
5137 /*
5138 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5139 */
5140 symbFreq = state->param.u.qam.symbol_rate;
5141 if (adcFrequency == 0) {
5142 /* Divide by zero */
5143 return -1;
5144 }
5145 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5146 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5147 16);
5148 if (lcSymbRate > 511)
5149 lcSymbRate = 511;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005150 status = Write16_0(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
5151 if (status < 0)
5152 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005153 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005154
Oliver Endrissebc7de22011-07-03 13:49:44 -03005155 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005156}
5157
5158/*============================================================================*/
5159
5160/**
5161* \brief Get QAM lock status.
5162* \param demod: instance of demod.
5163* \param channel: pointer to channel data.
5164* \return DRXStatus_t.
5165*/
5166
5167static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5168{
5169 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005170 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005171
Oliver Endrissebc7de22011-07-03 13:49:44 -03005172 status =
5173 scu_command(state,
5174 SCU_RAM_COMMAND_STANDARD_QAM |
5175 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5176 Result);
5177 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005178 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005179
5180 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005181 /* 0x0000 NOT LOCKED */
5182 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005183 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005184 /* 0x4000 DEMOD LOCKED */
5185 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005186 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005187 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5188 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005189 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005190 /* 0xC000 NEVER LOCKED */
5191 /* (system will never be able to lock to the signal) */
5192 /* TODO: check this, intermediate & standard specific lock states are not
5193 taken into account here */
5194 *pLockStatus = NEVER_LOCK;
5195 }
5196 return status;
5197}
5198
5199#define QAM_MIRROR__M 0x03
5200#define QAM_MIRROR_NORMAL 0x00
5201#define QAM_MIRRORED 0x01
5202#define QAM_MIRROR_AUTO_ON 0x02
5203#define QAM_LOCKRANGE__M 0x10
5204#define QAM_LOCKRANGE_NORMAL 0x10
5205
Oliver Endrissebc7de22011-07-03 13:49:44 -03005206static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5207 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005208{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005209 int status = 0;
5210 u8 parameterLen;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005211 u16 setEnvParameters[5];
5212 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5213 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005214
5215 do {
5216 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005217 STEP 1: reset demodulator
5218 resets FEC DI and FEC RS
5219 resets QAM block
5220 resets SCU variables
5221 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005222 status = Write16_0(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
5223 if (status < 0)
5224 break;
5225 status = Write16_0(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5226 if (status < 0)
5227 break;
5228 status = QAMResetQAM(state);
5229 if (status < 0)
5230 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005231
5232 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005233 STEP 2: configure demodulator
5234 -set env
5235 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5236 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005237 status = QAMSetSymbolrate(state);
5238 if (status < 0)
5239 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005240
5241 /* Env parameters */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005242 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005243 if (state->m_OperationMode == OM_QAM_ITU_C)
Oliver Endrissebc7de22011-07-03 13:49:44 -03005244 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005245 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005246 /* check for LOCKRANGE Extented */
5247 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005248 parameterLen = 4;
5249
5250 /* Set params */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005251 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005252 case QAM_256:
5253 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5254 break;
5255 case QAM_AUTO:
5256 case QAM_64:
5257 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5258 break;
5259 case QAM_16:
5260 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5261 break;
5262 case QAM_32:
5263 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5264 break;
5265 case QAM_128:
5266 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5267 break;
5268 default:
5269 status = -EINVAL;
5270 break;
5271 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005272 status = status;
5273 if (status < 0)
5274 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005275 setParamParameters[0] = state->m_Constellation; /* constellation */
5276 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005277
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005278 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5279 if (status < 0)
5280 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005281
5282
5283 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5284 setup constellation independent registers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005285#if 0
5286 status = SetFrequency (channel, tunerFreqOffset));
5287 if (status < 0)
5288 break;
5289#endif
5290 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5291 if (status < 0)
5292 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005293
5294 /* Setup BER measurement */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005295 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5296 if (status < 0)
5297 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005298
5299 /* Reset default values */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005300 status = Write16_0(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5301 if (status < 0)
5302 break;
5303 status = Write16_0(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5304 if (status < 0)
5305 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005306
Oliver Endrissebc7de22011-07-03 13:49:44 -03005307 /* Reset default LC values */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005308 status = Write16_0(state, QAM_LC_RATE_LIMIT__A, 3);
5309 if (status < 0)
5310 break;
5311 status = Write16_0(state, QAM_LC_LPF_FACTORP__A, 4);
5312 if (status < 0)
5313 break;
5314 status = Write16_0(state, QAM_LC_LPF_FACTORI__A, 4);
5315 if (status < 0)
5316 break;
5317 status = Write16_0(state, QAM_LC_MODE__A, 7);
5318 if (status < 0)
5319 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005320
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005321 status = Write16_0(state, QAM_LC_QUAL_TAB0__A, 1);
5322 if (status < 0)
5323 break;
5324 status = Write16_0(state, QAM_LC_QUAL_TAB1__A, 1);
5325 if (status < 0)
5326 break;
5327 status = Write16_0(state, QAM_LC_QUAL_TAB2__A, 1);
5328 if (status < 0)
5329 break;
5330 status = Write16_0(state, QAM_LC_QUAL_TAB3__A, 1);
5331 if (status < 0)
5332 break;
5333 status = Write16_0(state, QAM_LC_QUAL_TAB4__A, 2);
5334 if (status < 0)
5335 break;
5336 status = Write16_0(state, QAM_LC_QUAL_TAB5__A, 2);
5337 if (status < 0)
5338 break;
5339 status = Write16_0(state, QAM_LC_QUAL_TAB6__A, 2);
5340 if (status < 0)
5341 break;
5342 status = Write16_0(state, QAM_LC_QUAL_TAB8__A, 2);
5343 if (status < 0)
5344 break;
5345 status = Write16_0(state, QAM_LC_QUAL_TAB9__A, 2);
5346 if (status < 0)
5347 break;
5348 status = Write16_0(state, QAM_LC_QUAL_TAB10__A, 2);
5349 if (status < 0)
5350 break;
5351 status = Write16_0(state, QAM_LC_QUAL_TAB12__A, 2);
5352 if (status < 0)
5353 break;
5354 status = Write16_0(state, QAM_LC_QUAL_TAB15__A, 3);
5355 if (status < 0)
5356 break;
5357 status = Write16_0(state, QAM_LC_QUAL_TAB16__A, 3);
5358 if (status < 0)
5359 break;
5360 status = Write16_0(state, QAM_LC_QUAL_TAB20__A, 4);
5361 if (status < 0)
5362 break;
5363 status = Write16_0(state, QAM_LC_QUAL_TAB25__A, 4);
5364 if (status < 0)
5365 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005366
Oliver Endrissebc7de22011-07-03 13:49:44 -03005367 /* Mirroring, QAM-block starting point not inverted */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005368 status = Write16_0(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5369 if (status < 0)
5370 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005371
Oliver Endrissebc7de22011-07-03 13:49:44 -03005372 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005373 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5374 if (status < 0)
5375 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005376
Oliver Endrissebc7de22011-07-03 13:49:44 -03005377 /* STEP 4: constellation specific setup */
5378 switch (state->param.u.qam.modulation) {
5379 case QAM_16:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005380 status = SetQAM16(state);
5381 if (status < 0)
5382 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005383 break;
5384 case QAM_32:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005385 status = SetQAM32(state);
5386 if (status < 0)
5387 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005388 break;
5389 case QAM_AUTO:
5390 case QAM_64:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005391 status = SetQAM64(state);
5392 if (status < 0)
5393 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005394 break;
5395 case QAM_128:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005396 status = SetQAM128(state);
5397 if (status < 0)
5398 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005399 break;
5400 case QAM_256:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005401 status = SetQAM256(state);
5402 if (status < 0)
5403 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005404 break;
5405 default:
5406 return -1;
5407 break;
5408 } /* switch */
5409 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005410 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5411 if (status < 0)
5412 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005413
5414
Oliver Endrissebc7de22011-07-03 13:49:44 -03005415 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5416 /* extAttr->currentChannel.constellation = channel->constellation; */
5417 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005418 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5419 if (status < 0)
5420 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005421
Oliver Endrissebc7de22011-07-03 13:49:44 -03005422 /* Start processes */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005423 status = MPEGTSStart(state);
5424 if (status < 0)
5425 break;
5426 status = Write16_0(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5427 if (status < 0)
5428 break;
5429 status = Write16_0(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5430 if (status < 0)
5431 break;
5432 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5433 if (status < 0)
5434 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005435
Oliver Endrissebc7de22011-07-03 13:49:44 -03005436 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005437 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5438 if (status < 0)
5439 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005440
Oliver Endrissebc7de22011-07-03 13:49:44 -03005441 /* update global DRXK data container */
5442 /*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005443
Oliver Endrissebc7de22011-07-03 13:49:44 -03005444 /* All done, all OK */
5445 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005446
Oliver Endrissebc7de22011-07-03 13:49:44 -03005447 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005448 printk(KERN_ERR "drxk: %s %d\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005449
5450 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005451}
5452
Oliver Endrissebc7de22011-07-03 13:49:44 -03005453static int SetQAMStandard(struct drxk_state *state,
5454 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005455{
5456#ifdef DRXK_QAM_TAPS
5457#define DRXK_QAMA_TAPS_SELECT
5458#include "drxk_filters.h"
5459#undef DRXK_QAMA_TAPS_SELECT
5460#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03005461 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005462#endif
5463
Oliver Endrissebc7de22011-07-03 13:49:44 -03005464 do {
5465 /* added antenna switch */
5466 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005467
Oliver Endrissebc7de22011-07-03 13:49:44 -03005468 /* Ensure correct power-up mode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005469 status = PowerUpQAM(state);
5470 if (status < 0)
5471 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005472 /* Reset QAM block */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005473 status = QAMResetQAM(state);
5474 if (status < 0)
5475 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005476
Oliver Endrissebc7de22011-07-03 13:49:44 -03005477 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005478
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005479 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5480 if (status < 0)
5481 break;
5482 status = Write16_0(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5483 if (status < 0)
5484 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005485
Oliver Endrissebc7de22011-07-03 13:49:44 -03005486 /* Upload IQM Channel Filter settings by
5487 boot loader from ROM table */
5488 switch (oMode) {
5489 case OM_QAM_ITU_A:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005490 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5491 if (status < 0)
5492 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005493 break;
5494 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005495 status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5496 if (status < 0)
5497 break;
5498 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5499 if (status < 0)
5500 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005501 break;
5502 default:
5503 status = -EINVAL;
5504 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005505 status = status;
5506 if (status < 0)
5507 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005508
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005509 status = Write16_0(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5510 if (status < 0)
5511 break;
5512 status = Write16_0(state, IQM_CF_SYMMETRIC__A, 0);
5513 if (status < 0)
5514 break;
5515 status = Write16_0(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5516 if (status < 0)
5517 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005518
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005519 status = Write16_0(state, IQM_RC_STRETCH__A, 21);
5520 if (status < 0)
5521 break;
5522 status = Write16_0(state, IQM_AF_CLP_LEN__A, 0);
5523 if (status < 0)
5524 break;
5525 status = Write16_0(state, IQM_AF_CLP_TH__A, 448);
5526 if (status < 0)
5527 break;
5528 status = Write16_0(state, IQM_AF_SNS_LEN__A, 0);
5529 if (status < 0)
5530 break;
5531 status = Write16_0(state, IQM_CF_POW_MEAS_LEN__A, 0);
5532 if (status < 0)
5533 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005534
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005535 status = Write16_0(state, IQM_FS_ADJ_SEL__A, 1);
5536 if (status < 0)
5537 break;
5538 status = Write16_0(state, IQM_RC_ADJ_SEL__A, 1);
5539 if (status < 0)
5540 break;
5541 status = Write16_0(state, IQM_CF_ADJ_SEL__A, 1);
5542 if (status < 0)
5543 break;
5544 status = Write16_0(state, IQM_AF_UPD_SEL__A, 0);
5545 if (status < 0)
5546 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005547
Oliver Endrissebc7de22011-07-03 13:49:44 -03005548 /* IQM Impulse Noise Processing Unit */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005549 status = Write16_0(state, IQM_CF_CLP_VAL__A, 500);
5550 if (status < 0)
5551 break;
5552 status = Write16_0(state, IQM_CF_DATATH__A, 1000);
5553 if (status < 0)
5554 break;
5555 status = Write16_0(state, IQM_CF_BYPASSDET__A, 1);
5556 if (status < 0)
5557 break;
5558 status = Write16_0(state, IQM_CF_DET_LCT__A, 0);
5559 if (status < 0)
5560 break;
5561 status = Write16_0(state, IQM_CF_WND_LEN__A, 1);
5562 if (status < 0)
5563 break;
5564 status = Write16_0(state, IQM_CF_PKDTH__A, 1);
5565 if (status < 0)
5566 break;
5567 status = Write16_0(state, IQM_AF_INC_BYPASS__A, 1);
5568 if (status < 0)
5569 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005570
Oliver Endrissebc7de22011-07-03 13:49:44 -03005571 /* turn on IQMAF. Must be done before setAgc**() */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005572 status = SetIqmAf(state, true);
5573 if (status < 0)
5574 break;
5575 status = Write16_0(state, IQM_AF_START_LOCK__A, 0x01);
5576 if (status < 0)
5577 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005578
Oliver Endrissebc7de22011-07-03 13:49:44 -03005579 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005580 status = ADCSynchronization(state);
5581 if (status < 0)
5582 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005583
Oliver Endrissebc7de22011-07-03 13:49:44 -03005584 /* Set the FSM step period */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005585 status = Write16_0(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5586 if (status < 0)
5587 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005588
Oliver Endrissebc7de22011-07-03 13:49:44 -03005589 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005590 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5591 if (status < 0)
5592 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005593
Oliver Endrissebc7de22011-07-03 13:49:44 -03005594 /* No more resets of the IQM, current standard correctly set =>
5595 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005596
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005597 status = InitAGC(state, true);
5598 if (status < 0)
5599 break;
5600 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5601 if (status < 0)
5602 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005603
Oliver Endrissebc7de22011-07-03 13:49:44 -03005604 /* Configure AGC's */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005605 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5606 if (status < 0)
5607 break;
5608 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5609 if (status < 0)
5610 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005611
Oliver Endrissebc7de22011-07-03 13:49:44 -03005612 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005613 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5614 if (status < 0)
5615 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005616 } while (0);
5617 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005618}
5619
5620static int WriteGPIO(struct drxk_state *state)
5621{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005622 int status;
5623 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005624
Oliver Endrissebc7de22011-07-03 13:49:44 -03005625 do {
5626 /* stop lock indicator process */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005627 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5628 if (status < 0)
5629 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005630
Oliver Endrissebc7de22011-07-03 13:49:44 -03005631 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005632 status = Write16_0(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5633 if (status < 0)
5634 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005635
Oliver Endrissebc7de22011-07-03 13:49:44 -03005636 if (state->m_hasSAWSW) {
5637 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005638 status = Write16_0(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5639 if (status < 0)
5640 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005641
Oliver Endrissebc7de22011-07-03 13:49:44 -03005642 /* use corresponding bit in io data output registar */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005643 status = Read16_0(state, SIO_PDR_UIO_OUT_LO__A, &value);
5644 if (status < 0)
5645 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005646 if (state->m_GPIO == 0)
5647 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5648 else
5649 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5650 /* write back to io data output register */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005651 status = Write16_0(state, SIO_PDR_UIO_OUT_LO__A, value);
5652 if (status < 0)
5653 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005654
Oliver Endrissebc7de22011-07-03 13:49:44 -03005655 }
5656 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005657 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0x0000);
5658 if (status < 0)
5659 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005660 } while (0);
5661 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005662}
5663
5664static int SwitchAntennaToQAM(struct drxk_state *state)
5665{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005666 int status = -1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005667
Oliver Endrissebc7de22011-07-03 13:49:44 -03005668 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5669 if (state->m_GPIO != state->m_AntennaDVBC) {
5670 state->m_GPIO = state->m_AntennaDVBC;
5671 status = WriteGPIO(state);
5672 }
5673 }
5674 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005675}
5676
5677static int SwitchAntennaToDVBT(struct drxk_state *state)
5678{
5679 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005680
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005681 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5682 if (state->m_GPIO != state->m_AntennaDVBT) {
5683 state->m_GPIO = state->m_AntennaDVBT;
5684 status = WriteGPIO(state);
5685 }
5686 }
5687 return status;
5688}
5689
5690
5691static int PowerDownDevice(struct drxk_state *state)
5692{
5693 /* Power down to requested mode */
5694 /* Backup some register settings */
5695 /* Set pins with possible pull-ups connected to them in input mode */
5696 /* Analog power down */
5697 /* ADC power down */
5698 /* Power down device */
5699 int status;
5700 do {
5701 if (state->m_bPDownOpenBridge) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03005702 /* Open I2C bridge before power down of DRXK */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005703 status = ConfigureI2CBridge(state, true);
5704 if (status < 0)
5705 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005706 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005707 /* driver 0.9.0 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005708 status = DVBTEnableOFDMTokenRing(state, false);
5709 if (status < 0)
5710 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005711
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005712 status = Write16_0(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5713 if (status < 0)
5714 break;
5715 status = Write16_0(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5716 if (status < 0)
5717 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005718 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005719 status = HI_CfgCommand(state);
5720 if (status < 0)
5721 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005722 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005723
Oliver Endrissebc7de22011-07-03 13:49:44 -03005724 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005725 return -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005726
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005727 return 0;
5728}
5729
5730static int load_microcode(struct drxk_state *state, char *mc_name)
5731{
5732 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005733 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005734
5735 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5736 if (err < 0) {
5737 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005738 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005739 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005740 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005741 return err;
5742 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005743 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005744 release_firmware(fw);
5745 return err;
5746}
5747
5748static int init_drxk(struct drxk_state *state)
5749{
5750 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005751 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005752 u16 driverVersion;
5753
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005754 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
5755 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005756 status = PowerUpDevice(state);
5757 if (status < 0)
5758 break;
5759 status = DRXX_Open(state);
5760 if (status < 0)
5761 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005762 /* Soft reset of OFDM-, sys- and osc-clockdomain */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005763 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);
5764 if (status < 0)
5765 break;
5766 status = Write16_0(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5767 if (status < 0)
5768 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005769 /* TODO is this needed, if yes how much delay in worst case scenario */
5770 msleep(1);
5771 state->m_DRXK_A3_PATCH_CODE = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005772 status = GetDeviceCapabilities(state);
5773 if (status < 0)
5774 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005775
5776 /* Bridge delay, uses oscilator clock */
5777 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5778 /* SDA brdige delay */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005779 state->m_HICfgBridgeDelay =
5780 (u16) ((state->m_oscClockFreq / 1000) *
5781 HI_I2C_BRIDGE_DELAY) / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005782 /* Clipping */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005783 if (state->m_HICfgBridgeDelay >
5784 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
5785 state->m_HICfgBridgeDelay =
5786 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005787 }
5788 /* SCL bridge delay, same as SDA for now */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005789 state->m_HICfgBridgeDelay +=
5790 state->m_HICfgBridgeDelay <<
5791 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005792
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005793 status = InitHI(state);
5794 if (status < 0)
5795 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005796 /* disable various processes */
5797#if NOA1ROM
Oliver Endrissebc7de22011-07-03 13:49:44 -03005798 if (!(state->m_DRXK_A1_ROM_CODE)
5799 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005800#endif
5801 {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005802 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5803 if (status < 0)
5804 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005805 }
5806
5807 /* disable MPEG port */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005808 status = MPEGTSDisable(state);
5809 if (status < 0)
5810 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005811
5812 /* Stop AUD and SCU */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005813 status = Write16_0(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
5814 if (status < 0)
5815 break;
5816 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
5817 if (status < 0)
5818 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005819
5820 /* enable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005821 status = Write16_0(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
5822 if (status < 0)
5823 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005824
5825 /* include boot loader section */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005826 status = Write16_0(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
5827 if (status < 0)
5828 break;
5829 status = BLChainCmd(state, 0, 6, 100);
5830 if (status < 0)
5831 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005832
5833#if 0
5834 if (state->m_DRXK_A3_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005835 status = DownloadMicrocode(state, DRXK_A3_microcode, DRXK_A3_microcode_length);
5836 if (status < 0)
5837 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005838#else
5839 load_microcode(state, "drxk_a3.mc");
5840#endif
5841#if NOA1ROM
5842 if (state->m_DRXK_A2_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005843 status = DownloadMicrocode(state, DRXK_A2_microcode, DRXK_A2_microcode_length);
5844 if (status < 0)
5845 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005846#endif
5847 /* disable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005848 status = Write16_0(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
5849 if (status < 0)
5850 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005851
5852 /* Run SCU for a little while to initialize microcode version numbers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005853 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5854 if (status < 0)
5855 break;
5856 status = DRXX_Open(state);
5857 if (status < 0)
5858 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005859 /* added for test */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005860 msleep(30);
5861
5862 powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005863 status = CtrlPowerMode(state, &powerMode);
5864 if (status < 0)
5865 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005866
5867 /* Stamp driver version number in SCU data RAM in BCD code
5868 Done to enable field application engineers to retreive drxdriver version
5869 via I2C from SCU RAM.
5870 Not using SCU command interface for SCU register access since no
5871 microcode may be present.
Oliver Endrissebc7de22011-07-03 13:49:44 -03005872 */
5873 driverVersion =
5874 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
5875 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
5876 ((DRXK_VERSION_MAJOR % 10) << 4) +
5877 (DRXK_VERSION_MINOR % 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005878 status = Write16_0(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
5879 if (status < 0)
5880 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005881 driverVersion =
5882 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
5883 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
5884 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
5885 (DRXK_VERSION_PATCH % 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005886 status = Write16_0(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
5887 if (status < 0)
5888 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005889
Oliver Endrissebc7de22011-07-03 13:49:44 -03005890 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
5891 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
5892 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005893
5894 /* Dirty fix of default values for ROM/PATCH microcode
5895 Dirty because this fix makes it impossible to setup suitable values
5896 before calling DRX_Open. This solution requires changes to RF AGC speed
5897 to be done via the CTRL function after calling DRX_Open */
5898
Oliver Endrissebc7de22011-07-03 13:49:44 -03005899 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005900
5901 /* Reset driver debug flags to 0 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005902 status = Write16_0(state, SCU_RAM_DRIVER_DEBUG__A, 0);
5903 if (status < 0)
5904 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005905 /* driver 0.9.0 */
5906 /* Setup FEC OC:
5907 NOTE: No more full FEC resets allowed afterwards!! */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005908 status = Write16_0(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
5909 if (status < 0)
5910 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005911 /* MPEGTS functions are still the same */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005912 status = MPEGTSDtoInit(state);
5913 if (status < 0)
5914 break;
5915 status = MPEGTSStop(state);
5916 if (status < 0)
5917 break;
5918 status = MPEGTSConfigurePolarity(state);
5919 if (status < 0)
5920 break;
5921 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
5922 if (status < 0)
5923 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005924 /* added: configure GPIO */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005925 status = WriteGPIO(state);
5926 if (status < 0)
5927 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005928
Oliver Endrissebc7de22011-07-03 13:49:44 -03005929 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005930
5931 if (state->m_bPowerDown) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005932 status = PowerDownDevice(state);
5933 if (status < 0)
5934 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005935 state->m_DrxkState = DRXK_POWERED_DOWN;
5936 } else
5937 state->m_DrxkState = DRXK_STOPPED;
5938 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005939 }
5940
5941 return 0;
5942}
5943
Oliver Endrissebc7de22011-07-03 13:49:44 -03005944static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005945{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005946 struct drxk_state *state = fe->demodulator_priv;
5947
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005948 kfree(state);
5949}
5950
Oliver Endrissebc7de22011-07-03 13:49:44 -03005951static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005952{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005953 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005954
Oliver Endrissebc7de22011-07-03 13:49:44 -03005955 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005956 return -EBUSY;
5957 SetOperationMode(state, OM_QAM_ITU_A);
5958 return 0;
5959}
5960
Oliver Endrissebc7de22011-07-03 13:49:44 -03005961static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005962{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005963 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005964
5965 ShutDown(state);
5966 mutex_unlock(&state->ctlock);
5967 return 0;
5968}
5969
Oliver Endrissebc7de22011-07-03 13:49:44 -03005970static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005971{
5972 struct drxk_state *state = fe->demodulator_priv;
5973
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005974 /* printk(KERN_DEBUG "drxk: drxk_gate %d\n", enable); */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005975 return ConfigureI2CBridge(state, enable ? true : false);
5976}
5977
Oliver Endrissebc7de22011-07-03 13:49:44 -03005978static int drxk_set_parameters(struct dvb_frontend *fe,
5979 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005980{
5981 struct drxk_state *state = fe->demodulator_priv;
5982 u32 IF;
5983
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005984 if (fe->ops.i2c_gate_ctrl)
5985 fe->ops.i2c_gate_ctrl(fe, 1);
5986 if (fe->ops.tuner_ops.set_params)
5987 fe->ops.tuner_ops.set_params(fe, p);
5988 if (fe->ops.i2c_gate_ctrl)
5989 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005990 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005991 fe->ops.tuner_ops.get_frequency(fe, &IF);
5992 Start(state, 0, IF);
5993
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005994 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005995
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005996 return 0;
5997}
5998
Oliver Endrissebc7de22011-07-03 13:49:44 -03005999static int drxk_c_get_frontend(struct dvb_frontend *fe,
6000 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006001{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006002 return 0;
6003}
6004
6005static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6006{
6007 struct drxk_state *state = fe->demodulator_priv;
6008 u32 stat;
6009
Oliver Endrissebc7de22011-07-03 13:49:44 -03006010 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006011 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006012 if (stat == MPEG_LOCK)
6013 *status |= 0x1f;
6014 if (stat == FEC_LOCK)
6015 *status |= 0x0f;
6016 if (stat == DEMOD_LOCK)
6017 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006018 return 0;
6019}
6020
6021static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6022{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006023 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006024 return 0;
6025}
6026
Oliver Endrissebc7de22011-07-03 13:49:44 -03006027static int drxk_read_signal_strength(struct dvb_frontend *fe,
6028 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006029{
6030 struct drxk_state *state = fe->demodulator_priv;
6031 u32 val;
6032
6033 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006034 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006035 return 0;
6036}
6037
6038static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6039{
6040 struct drxk_state *state = fe->demodulator_priv;
6041 s32 snr2;
6042
6043 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006044 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006045 return 0;
6046}
6047
6048static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6049{
6050 struct drxk_state *state = fe->demodulator_priv;
6051 u16 err;
6052
6053 DVBTQAMGetAccPktErr(state, &err);
6054 *ucblocks = (u32) err;
6055 return 0;
6056}
6057
Oliver Endrissebc7de22011-07-03 13:49:44 -03006058static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6059 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006060{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006061 sets->min_delay_ms = 3000;
6062 sets->max_drift = 0;
6063 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006064 return 0;
6065}
6066
Oliver Endrissebc7de22011-07-03 13:49:44 -03006067static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006068{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006069#if 0
6070 struct drxk_state *state = fe->demodulator_priv;
6071
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006072 printk(KERN_DEBUG "drxk: %s\n", __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006073 kfree(state);
6074#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006075}
6076
Oliver Endrissebc7de22011-07-03 13:49:44 -03006077static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006078{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006079 struct drxk_state *state = fe->demodulator_priv;
6080 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006081 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006082 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006083 return 0;
6084}
6085
Oliver Endrissebc7de22011-07-03 13:49:44 -03006086static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006087{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006088 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006089 mutex_unlock(&state->ctlock);
6090 return 0;
6091}
6092
Oliver Endrissebc7de22011-07-03 13:49:44 -03006093static int drxk_t_get_frontend(struct dvb_frontend *fe,
6094 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006095{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006096 return 0;
6097}
6098
6099static struct dvb_frontend_ops drxk_c_ops = {
6100 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006101 .name = "DRXK DVB-C",
6102 .type = FE_QAM,
6103 .frequency_stepsize = 62500,
6104 .frequency_min = 47000000,
6105 .frequency_max = 862000000,
6106 .symbol_rate_min = 870000,
6107 .symbol_rate_max = 11700000,
6108 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6109 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006110 .release = drxk_c_release,
6111 .init = drxk_c_init,
6112 .sleep = drxk_c_sleep,
6113 .i2c_gate_ctrl = drxk_gate_ctrl,
6114
6115 .set_frontend = drxk_set_parameters,
6116 .get_frontend = drxk_c_get_frontend,
6117 .get_tune_settings = drxk_c_get_tune_settings,
6118
6119 .read_status = drxk_read_status,
6120 .read_ber = drxk_read_ber,
6121 .read_signal_strength = drxk_read_signal_strength,
6122 .read_snr = drxk_read_snr,
6123 .read_ucblocks = drxk_read_ucblocks,
6124};
6125
6126static struct dvb_frontend_ops drxk_t_ops = {
6127 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006128 .name = "DRXK DVB-T",
6129 .type = FE_OFDM,
6130 .frequency_min = 47125000,
6131 .frequency_max = 865000000,
6132 .frequency_stepsize = 166667,
6133 .frequency_tolerance = 0,
6134 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6135 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6136 FE_CAN_FEC_AUTO |
6137 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6138 FE_CAN_QAM_AUTO |
6139 FE_CAN_TRANSMISSION_MODE_AUTO |
6140 FE_CAN_GUARD_INTERVAL_AUTO |
6141 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006142 .release = drxk_t_release,
6143 .init = drxk_t_init,
6144 .sleep = drxk_t_sleep,
6145 .i2c_gate_ctrl = drxk_gate_ctrl,
6146
6147 .set_frontend = drxk_set_parameters,
6148 .get_frontend = drxk_t_get_frontend,
6149
6150 .read_status = drxk_read_status,
6151 .read_ber = drxk_read_ber,
6152 .read_signal_strength = drxk_read_signal_strength,
6153 .read_snr = drxk_read_snr,
6154 .read_ucblocks = drxk_read_ucblocks,
6155};
6156
6157struct dvb_frontend *drxk_attach(struct i2c_adapter *i2c, u8 adr,
6158 struct dvb_frontend **fe_t)
6159{
6160 struct drxk_state *state = NULL;
6161
Oliver Endrissebc7de22011-07-03 13:49:44 -03006162 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006163 if (!state)
6164 return NULL;
6165
Oliver Endrissebc7de22011-07-03 13:49:44 -03006166 state->i2c = i2c;
6167 state->demod_address = adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006168
6169 mutex_init(&state->mutex);
6170 mutex_init(&state->ctlock);
6171
Oliver Endrissebc7de22011-07-03 13:49:44 -03006172 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6173 sizeof(struct dvb_frontend_ops));
6174 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6175 sizeof(struct dvb_frontend_ops));
6176 state->c_frontend.demodulator_priv = state;
6177 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006178
6179 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006180 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006181 goto error;
6182 *fe_t = &state->t_frontend;
6183 return &state->c_frontend;
6184
6185error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006186 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006187 kfree(state);
6188 return NULL;
6189}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006190EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006191
6192MODULE_DESCRIPTION("DRX-K driver");
6193MODULE_AUTHOR("Ralph Metzler");
6194MODULE_LICENSE("GPL");