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