blob: d351e6a630fc748abe628014aca3874e5f3720ce [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 Chehab2da67502011-07-04 17:39:21 -0300176static unsigned int debug;
177module_param(debug, int, 0644);
178MODULE_PARM_DESC(debug, "enable debug messages");
179
180#define dprintk(level, fmt, arg...) do { \
181if (debug >= level) \
182 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
183} while (0)
184
185
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300186static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300187{
188 u64 tmp64;
189
Oliver Endrissebc7de22011-07-03 13:49:44 -0300190 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300191 do_div(tmp64, c);
192
193 return (u32) tmp64;
194}
195
196inline u32 Frac28a(u32 a, u32 c)
197{
198 int i = 0;
199 u32 Q1 = 0;
200 u32 R0 = 0;
201
Oliver Endrissebc7de22011-07-03 13:49:44 -0300202 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
203 Q1 = a / c; /* integer part, only the 4 least significant bits
204 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300205
206 /* division using radix 16, 7 nibbles in the result */
207 for (i = 0; i < 7; i++) {
208 Q1 = (Q1 << 4) | (R0 / c);
209 R0 = (R0 % c) << 4;
210 }
211 /* rounding */
212 if ((R0 >> 3) >= c)
213 Q1++;
214
215 return Q1;
216}
217
218static u32 Log10Times100(u32 x)
219{
220 static const u8 scale = 15;
221 static const u8 indexWidth = 5;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300222 u8 i = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300223 u32 y = 0;
224 u32 d = 0;
225 u32 k = 0;
226 u32 r = 0;
227 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300228 log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
229 0 <= n < ((1<<INDEXWIDTH)+1)
230 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300231
232 static const u32 log2lut[] = {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300233 0, /* 0.000000 */
234 290941, /* 290941.300628 */
235 573196, /* 573196.476418 */
236 847269, /* 847269.179851 */
237 1113620, /* 1113620.489452 */
238 1372674, /* 1372673.576986 */
239 1624818, /* 1624817.752104 */
240 1870412, /* 1870411.981536 */
241 2109788, /* 2109787.962654 */
242 2343253, /* 2343252.817465 */
243 2571091, /* 2571091.461923 */
244 2793569, /* 2793568.696416 */
245 3010931, /* 3010931.055901 */
246 3223408, /* 3223408.452106 */
247 3431216, /* 3431215.635215 */
248 3634553, /* 3634553.498355 */
249 3833610, /* 3833610.244726 */
250 4028562, /* 4028562.434393 */
251 4219576, /* 4219575.925308 */
252 4406807, /* 4406806.721144 */
253 4590402, /* 4590401.736809 */
254 4770499, /* 4770499.491025 */
255 4947231, /* 4947230.734179 */
256 5120719, /* 5120719.018555 */
257 5291081, /* 5291081.217197 */
258 5458428, /* 5458427.996830 */
259 5622864, /* 5622864.249668 */
260 5784489, /* 5784489.488298 */
261 5943398, /* 5943398.207380 */
262 6099680, /* 6099680.215452 */
263 6253421, /* 6253420.939751 */
264 6404702, /* 6404701.706649 */
265 6553600, /* 6553600.000000 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300266 };
267
268
269 if (x == 0)
Oliver Endrissebc7de22011-07-03 13:49:44 -0300270 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300271
272 /* Scale x (normalize) */
273 /* computing y in log(x/y) = log(x) - log(y) */
274 if ((x & ((0xffffffff) << (scale + 1))) == 0) {
275 for (k = scale; k > 0; k--) {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300276 if (x & (((u32) 1) << scale))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300277 break;
278 x <<= 1;
279 }
280 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300281 for (k = scale; k < 31; k++) {
282 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300283 break;
284 x >>= 1;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300285 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300286 }
287 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300288 Now x has binary point between bit[scale] and bit[scale-1]
289 and 1.0 <= x < 2.0 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300290
291 /* correction for divison: log(x) = log(x/y)+log(y) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300292 y = k * ((((u32) 1) << scale) * 200);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300293
294 /* remove integer part */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300295 x &= ((((u32) 1) << scale) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300296 /* get index */
297 i = (u8) (x >> (scale - indexWidth));
298 /* compute delta (x - a) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300299 d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300300 /* compute log, multiplication (d* (..)) must be within range ! */
301 y += log2lut[i] +
Oliver Endrissebc7de22011-07-03 13:49:44 -0300302 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300303 /* Conver to log10() */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300304 y /= 108853; /* (log2(10) << scale) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300305 r = (y >> 1);
306 /* rounding */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300307 if (y & ((u32) 1))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300308 r++;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300309 return r;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300310}
311
312/****************************************************************************/
313/* I2C **********************************************************************/
314/****************************************************************************/
315
316static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val)
317{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300318 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
319 .buf = val, .len = 1}
320 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300321 return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
322}
323
324static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
325{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300326 struct i2c_msg msg = {
327 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300328
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300329 dprintk(3, ":");
330 if (debug > 2) {
331 int i;
332 for (i = 0; i < len; i++)
333 printk(KERN_CONT " %02x", data[i]);
334 printk(KERN_CONT "\n");
335 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300336 if (i2c_transfer(adap, &msg, 1) != 1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300337 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300338 return -1;
339 }
340 return 0;
341}
342
343static int i2c_read(struct i2c_adapter *adap,
344 u8 adr, u8 *msg, int len, u8 *answ, int alen)
345{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300346 struct i2c_msg msgs[2] = { {.addr = adr, .flags = 0,
347 .buf = msg, .len = len},
348 {.addr = adr, .flags = I2C_M_RD,
349 .buf = answ, .len = alen}
350 };
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300351 dprintk(3, ":");
352 if (debug > 2) {
353 int i;
354 for (i = 0; i < len; i++)
355 printk(KERN_CONT " %02x", msg[i]);
356 printk(KERN_CONT "\n");
357 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300358 if (i2c_transfer(adap, msgs, 2) != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300359 if (debug > 2)
360 printk(KERN_CONT ": ERROR!\n");
361
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300362 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300363 return -1;
364 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300365 if (debug > 2) {
366 int i;
367 printk(KERN_CONT ": Read ");
368 for (i = 0; i < len; i++)
369 printk(KERN_CONT " %02x", msg[i]);
370 printk(KERN_CONT "\n");
371 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300372 return 0;
373}
374
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300375static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300376{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300377 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300378#ifdef I2C_LONG_ADR
379 flags |= 0xC0;
380#endif
381 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
382 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
383 mm1[1] = ((reg >> 16) & 0xFF);
384 mm1[2] = ((reg >> 24) & 0xFF) | flags;
385 mm1[3] = ((reg >> 7) & 0xFF);
386 len = 4;
387 } else {
388 mm1[0] = ((reg << 1) & 0xFF);
389 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
390 len = 2;
391 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300392 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300393 if (i2c_read(state->i2c, adr, mm1, len, mm2, 2) < 0)
394 return -1;
395 if (data)
396 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300397
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300398 return 0;
399}
400
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300401static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300402{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300403 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300404}
405
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300406static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300407{
408 u8 adr = state->demod_address, mm1[4], mm2[4], len;
409#ifdef I2C_LONG_ADR
410 flags |= 0xC0;
411#endif
412 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
413 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
414 mm1[1] = ((reg >> 16) & 0xFF);
415 mm1[2] = ((reg >> 24) & 0xFF) | flags;
416 mm1[3] = ((reg >> 7) & 0xFF);
417 len = 4;
418 } else {
419 mm1[0] = ((reg << 1) & 0xFF);
420 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
421 len = 2;
422 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300423 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300424 if (i2c_read(state->i2c, adr, mm1, len, mm2, 4) < 0)
425 return -1;
426 if (data)
427 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300428 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300429
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300430 return 0;
431}
432
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300433static int read32(struct drxk_state *state, u32 reg, u32 *data)
434{
435 return read32_flags(state, reg, data, 0);
436}
437
438static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300439{
440 u8 adr = state->demod_address, mm[6], len;
441#ifdef I2C_LONG_ADR
442 flags |= 0xC0;
443#endif
444 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
445 mm[0] = (((reg << 1) & 0xFF) | 0x01);
446 mm[1] = ((reg >> 16) & 0xFF);
447 mm[2] = ((reg >> 24) & 0xFF) | flags;
448 mm[3] = ((reg >> 7) & 0xFF);
449 len = 4;
450 } else {
451 mm[0] = ((reg << 1) & 0xFF);
452 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
453 len = 2;
454 }
455 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300456 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300457
458 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300459 if (i2c_write(state->i2c, adr, mm, len + 2) < 0)
460 return -1;
461 return 0;
462}
463
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300464static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300465{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300466 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300467}
468
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300469static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300470{
471 u8 adr = state->demod_address, mm[8], len;
472#ifdef I2C_LONG_ADR
473 flags |= 0xC0;
474#endif
475 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
476 mm[0] = (((reg << 1) & 0xFF) | 0x01);
477 mm[1] = ((reg >> 16) & 0xFF);
478 mm[2] = ((reg >> 24) & 0xFF) | flags;
479 mm[3] = ((reg >> 7) & 0xFF);
480 len = 4;
481 } else {
482 mm[0] = ((reg << 1) & 0xFF);
483 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
484 len = 2;
485 }
486 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300487 mm[len + 1] = (data >> 8) & 0xff;
488 mm[len + 2] = (data >> 16) & 0xff;
489 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300490 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300491 if (i2c_write(state->i2c, adr, mm, len + 4) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300492 return -1;
493 return 0;
494}
495
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300496static int write32(struct drxk_state *state, u32 reg, u32 data)
497{
498 return write32_flags(state, reg, data, 0);
499}
500
501static int write_block(struct drxk_state *state, u32 Address,
502 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300503{
504 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300505 u8 Flags = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300506#ifdef I2C_LONG_ADR
507 Flags |= 0xC0;
508#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -0300509 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300510 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300511 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300512 u8 *AdrBuf = &state->Chunk[0];
513 u32 AdrLength = 0;
514
Oliver Endrissebc7de22011-07-03 13:49:44 -0300515 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
516 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
517 AdrBuf[1] = ((Address >> 16) & 0xFF);
518 AdrBuf[2] = ((Address >> 24) & 0xFF);
519 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300520 AdrBuf[2] |= Flags;
521 AdrLength = 4;
522 if (Chunk == state->m_ChunkSize)
523 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300524 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300525 AdrBuf[0] = ((Address << 1) & 0xFF);
526 AdrBuf[1] = (((Address >> 16) & 0x0F) |
527 ((Address >> 18) & 0xF0));
528 AdrLength = 2;
529 }
530 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300531 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
532 if (debug > 1) {
533 int i;
534 if (pBlock)
535 for (i = 0; i < Chunk; i++)
536 printk(KERN_CONT " %02x", pBlock[i]);
537 printk(KERN_CONT "\n");
538 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300539 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300540 &state->Chunk[0], Chunk + AdrLength);
541 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300542 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
543 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300544 break;
545 }
546 pBlock += Chunk;
547 Address += (Chunk >> 1);
548 BlkSize -= Chunk;
549 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300550 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300551}
552
553#ifndef DRXK_MAX_RETRIES_POWERUP
554#define DRXK_MAX_RETRIES_POWERUP 20
555#endif
556
557int PowerUpDevice(struct drxk_state *state)
558{
559 int status;
560 u8 data = 0;
561 u16 retryCount = 0;
562
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300563 dprintk(1, "\n");
564
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300565 status = i2c_read1(state->i2c, state->demod_address, &data);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300566 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300567 do {
568 data = 0;
569 if (i2c_write(state->i2c,
570 state->demod_address, &data, 1) < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300571 printk(KERN_ERR "drxk: powerup failed\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300572 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300573 retryCount++;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300574 } while (i2c_read1(state->i2c,
575 state->demod_address, &data) < 0 &&
576 (retryCount < DRXK_MAX_RETRIES_POWERUP));
577 if (retryCount >= DRXK_MAX_RETRIES_POWERUP)
578 return -1;
579 do {
580 /* Make sure all clk domains are active */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300581 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300582 if (status < 0)
583 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300584 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300585 if (status < 0)
586 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300587 /* Enable pll lock tests */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300588 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300589 if (status < 0)
590 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300591 state->m_currentPowerMode = DRX_POWER_UP;
592 } while (0);
593 return status;
594}
595
596
597static int init_state(struct drxk_state *state)
598{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300599 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
600 u32 ulVSBIfAgcOutputLevel = 0;
601 u32 ulVSBIfAgcMinLevel = 0;
602 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
603 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300604
Oliver Endrissebc7de22011-07-03 13:49:44 -0300605 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
606 u32 ulVSBRfAgcOutputLevel = 0;
607 u32 ulVSBRfAgcMinLevel = 0;
608 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
609 u32 ulVSBRfAgcSpeed = 3;
610 u32 ulVSBRfAgcTop = 9500;
611 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300612
Oliver Endrissebc7de22011-07-03 13:49:44 -0300613 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
614 u32 ulATVIfAgcOutputLevel = 0;
615 u32 ulATVIfAgcMinLevel = 0;
616 u32 ulATVIfAgcMaxLevel = 0;
617 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300618
Oliver Endrissebc7de22011-07-03 13:49:44 -0300619 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
620 u32 ulATVRfAgcOutputLevel = 0;
621 u32 ulATVRfAgcMinLevel = 0;
622 u32 ulATVRfAgcMaxLevel = 0;
623 u32 ulATVRfAgcTop = 9500;
624 u32 ulATVRfAgcCutOffCurrent = 4000;
625 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300626
627 u32 ulQual83 = DEFAULT_MER_83;
628 u32 ulQual93 = DEFAULT_MER_93;
629
630 u32 ulDVBTStaticTSClock = 1;
631 u32 ulDVBCStaticTSClock = 1;
632
633 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
634 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
635
636 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
637 /* io_pad_cfg_mode output mode is drive always */
638 /* io_pad_cfg_drive is set to power 2 (23 mA) */
639 u32 ulGPIOCfg = 0x0113;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300640 u32 ulGPIO = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300641 u32 ulSerialMode = 1;
642 u32 ulInvertTSClock = 0;
643 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
644 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
645 u32 ulDVBTBitrate = 50000000;
646 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
647
648 u32 ulInsertRSByte = 0;
649
650 u32 ulRfMirror = 1;
651 u32 ulPowerDown = 0;
652
653 u32 ulAntennaDVBT = 1;
654 u32 ulAntennaDVBC = 0;
655 u32 ulAntennaSwitchDVBTDVBC = 0;
656
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300657 dprintk(1, "\n");
658
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300659 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300660 state->m_hasDVBT = false;
661 state->m_hasDVBC = false;
662 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300663 state->m_hasOOB = false;
664 state->m_hasAudio = false;
665
666 state->m_ChunkSize = 124;
667
668 state->m_oscClockFreq = 0;
669 state->m_smartAntInverted = false;
670 state->m_bPDownOpenBridge = false;
671
672 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300673 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300674 /* Timing div, 250ns/Psys */
675 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
676 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
677 HI_I2C_DELAY) / 1000;
678 /* Clipping */
679 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
680 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
681 state->m_HICfgWakeUpKey = (state->demod_address << 1);
682 /* port/bridge/power down ctrl */
683 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
684
685 state->m_bPowerDown = (ulPowerDown != 0);
686
687 state->m_DRXK_A1_PATCH_CODE = false;
688 state->m_DRXK_A1_ROM_CODE = false;
689 state->m_DRXK_A2_ROM_CODE = false;
690 state->m_DRXK_A3_ROM_CODE = false;
691 state->m_DRXK_A2_PATCH_CODE = false;
692 state->m_DRXK_A3_PATCH_CODE = false;
693
694 /* Init AGC and PGA parameters */
695 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300696 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
697 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
698 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
699 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
700 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300701 state->m_vsbPgaCfg = 140;
702
703 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300704 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
705 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
706 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
707 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
708 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
709 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
710 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
711 state->m_vsbPreSawCfg.reference = 0x07;
712 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300713
714 state->m_Quality83percent = DEFAULT_MER_83;
715 state->m_Quality93percent = DEFAULT_MER_93;
716 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
717 state->m_Quality83percent = ulQual83;
718 state->m_Quality93percent = ulQual93;
719 }
720
721 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300722 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
723 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
724 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
725 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
726 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300727
728 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300729 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
730 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
731 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
732 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
733 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
734 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
735 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
736 state->m_atvPreSawCfg.reference = 0x04;
737 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300738
739
740 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300741 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
742 state->m_dvbtRfAgcCfg.outputLevel = 0;
743 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
744 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
745 state->m_dvbtRfAgcCfg.top = 0x2100;
746 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
747 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300748
749
750 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300751 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
752 state->m_dvbtIfAgcCfg.outputLevel = 0;
753 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
754 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
755 state->m_dvbtIfAgcCfg.top = 13424;
756 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
757 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300758 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300759 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
760 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300761
Oliver Endrissebc7de22011-07-03 13:49:44 -0300762 state->m_dvbtPreSawCfg.reference = 4;
763 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300764
765 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300766 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
767 state->m_qamRfAgcCfg.outputLevel = 0;
768 state->m_qamRfAgcCfg.minOutputLevel = 6023;
769 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
770 state->m_qamRfAgcCfg.top = 0x2380;
771 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
772 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300773
774 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300775 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
776 state->m_qamIfAgcCfg.outputLevel = 0;
777 state->m_qamIfAgcCfg.minOutputLevel = 0;
778 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
779 state->m_qamIfAgcCfg.top = 0x0511;
780 state->m_qamIfAgcCfg.cutOffCurrent = 0;
781 state->m_qamIfAgcCfg.speed = 3;
782 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300783 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
784
Oliver Endrissebc7de22011-07-03 13:49:44 -0300785 state->m_qamPgaCfg = 140;
786 state->m_qamPreSawCfg.reference = 4;
787 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300788
789 state->m_OperationMode = OM_NONE;
790 state->m_DrxkState = DRXK_UNINITIALIZED;
791
792 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300793 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
794 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
795 state->m_enableParallel = true; /* If TRUE;
796 parallel out otherwise serial */
797 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
798 state->m_invertERR = false; /* If TRUE; invert ERR signal */
799 state->m_invertSTR = false; /* If TRUE; invert STR signals */
800 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
801 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300802 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300803 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300804 /* If TRUE; static MPEG clockrate will be used;
805 otherwise clockrate will adapt to the bitrate of the TS */
806
807 state->m_DVBTBitrate = ulDVBTBitrate;
808 state->m_DVBCBitrate = ulDVBCBitrate;
809
810 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
811 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
812
813 /* Maximum bitrate in b/s in case static clockrate is selected */
814 state->m_mpegTsStaticBitrate = 19392658;
815 state->m_disableTEIhandling = false;
816
817 if (ulInsertRSByte)
818 state->m_insertRSByte = true;
819
820 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
821 if (ulMpegLockTimeOut < 10000)
822 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
823 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
824 if (ulDemodLockTimeOut < 10000)
825 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
826
Oliver Endrissebc7de22011-07-03 13:49:44 -0300827 /* QAM defaults */
828 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300829 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300830 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
831 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300832
833 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
834 state->m_agcFastClipCtrlDelay = 0;
835
836 state->m_GPIOCfg = (ulGPIOCfg);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300837 state->m_GPIO = (ulGPIO == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300838
839 state->m_AntennaDVBT = (ulAntennaDVBT == 0 ? 0 : 1);
840 state->m_AntennaDVBC = (ulAntennaDVBC == 0 ? 0 : 1);
841 state->m_AntennaSwitchDVBTDVBC =
Oliver Endrissebc7de22011-07-03 13:49:44 -0300842 (ulAntennaSwitchDVBTDVBC == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300843
844 state->m_bPowerDown = false;
845 state->m_currentPowerMode = DRX_POWER_DOWN;
846
847 state->m_enableParallel = (ulSerialMode == 0);
848
849 state->m_rfmirror = (ulRfMirror == 0);
850 state->m_IfAgcPol = false;
851 return 0;
852}
853
854static int DRXX_Open(struct drxk_state *state)
855{
856 int status = 0;
857 u32 jtag = 0;
858 u16 bid = 0;
859 u16 key = 0;
860
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300861 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300862 do {
863 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300864 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300865 if (status < 0)
866 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300867 /* Check device id */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300868 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300869 if (status < 0)
870 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300871 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300872 if (status < 0)
873 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300874 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300875 if (status < 0)
876 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300877 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300878 if (status < 0)
879 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300880 status = write16(state, SIO_TOP_COMM_KEY__A, key);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300881 if (status < 0)
882 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300883 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300884 return status;
885}
886
887static int GetDeviceCapabilities(struct drxk_state *state)
888{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300889 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300890 u32 sioTopJtagidLo = 0;
891 int status;
892
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300893 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300894 do {
895 /* driver 0.9.0 */
896 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300897 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300898 if (status < 0)
899 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300900
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300901 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300902 if (status < 0)
903 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300904 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300905 if (status < 0)
906 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300907 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300908 if (status < 0)
909 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300910
911 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
912 case 0:
913 /* ignore (bypass ?) */
914 break;
915 case 1:
916 /* 27 MHz */
917 state->m_oscClockFreq = 27000;
918 break;
919 case 2:
920 /* 20.25 MHz */
921 state->m_oscClockFreq = 20250;
922 break;
923 case 3:
924 /* 4 MHz */
925 state->m_oscClockFreq = 20250;
926 break;
927 default:
928 return -1;
929 }
930 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300931 Determine device capabilities
932 Based on pinning v14
933 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300934 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300935 if (status < 0)
936 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300937 /* driver 0.9.0 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300938 switch ((sioTopJtagidLo >> 29) & 0xF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300939 case 0:
940 state->m_deviceSpin = DRXK_SPIN_A1;
941 break;
942 case 2:
943 state->m_deviceSpin = DRXK_SPIN_A2;
944 break;
945 case 3:
946 state->m_deviceSpin = DRXK_SPIN_A3;
947 break;
948 default:
949 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
950 status = -1;
951 break;
952 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300953 switch ((sioTopJtagidLo >> 12) & 0xFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300954 case 0x13:
955 /* typeId = DRX3913K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300956 state->m_hasLNA = false;
957 state->m_hasOOB = false;
958 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300959 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300960 state->m_hasDVBT = true;
961 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300962 state->m_hasSAWSW = true;
963 state->m_hasGPIO2 = false;
964 state->m_hasGPIO1 = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300965 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300966 break;
967 case 0x15:
968 /* typeId = DRX3915K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300969 state->m_hasLNA = false;
970 state->m_hasOOB = false;
971 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300972 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300973 state->m_hasDVBT = true;
974 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300975 state->m_hasSAWSW = true;
976 state->m_hasGPIO2 = true;
977 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300978 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300979 break;
980 case 0x16:
981 /* typeId = DRX3916K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300982 state->m_hasLNA = false;
983 state->m_hasOOB = false;
984 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300985 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300986 state->m_hasDVBT = true;
987 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300988 state->m_hasSAWSW = true;
989 state->m_hasGPIO2 = true;
990 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300991 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300992 break;
993 case 0x18:
994 /* typeId = DRX3918K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300995 state->m_hasLNA = false;
996 state->m_hasOOB = false;
997 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300998 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300999 state->m_hasDVBT = true;
1000 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001001 state->m_hasSAWSW = true;
1002 state->m_hasGPIO2 = true;
1003 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001004 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001005 break;
1006 case 0x21:
1007 /* typeId = DRX3921K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001008 state->m_hasLNA = false;
1009 state->m_hasOOB = false;
1010 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001011 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001012 state->m_hasDVBT = true;
1013 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001014 state->m_hasSAWSW = true;
1015 state->m_hasGPIO2 = true;
1016 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001017 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001018 break;
1019 case 0x23:
1020 /* typeId = DRX3923K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001021 state->m_hasLNA = false;
1022 state->m_hasOOB = false;
1023 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001024 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001025 state->m_hasDVBT = true;
1026 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001027 state->m_hasSAWSW = true;
1028 state->m_hasGPIO2 = true;
1029 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001030 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001031 break;
1032 case 0x25:
1033 /* typeId = DRX3925K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001034 state->m_hasLNA = false;
1035 state->m_hasOOB = false;
1036 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001037 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001038 state->m_hasDVBT = true;
1039 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001040 state->m_hasSAWSW = true;
1041 state->m_hasGPIO2 = true;
1042 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001043 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001044 break;
1045 case 0x26:
1046 /* typeId = DRX3926K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001047 state->m_hasLNA = false;
1048 state->m_hasOOB = false;
1049 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001050 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001051 state->m_hasDVBT = true;
1052 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001053 state->m_hasSAWSW = true;
1054 state->m_hasGPIO2 = true;
1055 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001056 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001057 break;
1058 default:
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001059 printk(KERN_ERR "drxk: DeviceID not supported = %02x\n",
Oliver Endrissebc7de22011-07-03 13:49:44 -03001060 ((sioTopJtagidLo >> 12) & 0xFF));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001061 status = -1;
1062 break;
1063 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001064 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001065 return status;
1066}
1067
1068static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1069{
1070 int status;
1071 bool powerdown_cmd;
1072
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001073 dprintk(1, "\n");
1074
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001075 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001076 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001077 if (status < 0)
1078 return status;
1079 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1080 msleep(1);
1081
1082 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001083 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1084 ((state->m_HICfgCtrl) &
1085 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1086 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001087 if (powerdown_cmd == false) {
1088 /* Wait until command rdy */
1089 u32 retryCount = 0;
1090 u16 waitCmd;
1091
1092 do {
1093 msleep(1);
1094 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001095 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1096 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001097 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1098 && (waitCmd != 0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001099
1100 if (status == 0)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001101 status = read16(state, SIO_HI_RA_RAM_RES__A,
1102 pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001103 }
1104 return status;
1105}
1106
1107static int HI_CfgCommand(struct drxk_state *state)
1108{
1109 int status;
1110
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001111 dprintk(1, "\n");
1112
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001113 mutex_lock(&state->mutex);
1114 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001115 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001116 if (status < 0)
1117 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001118 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001119 if (status < 0)
1120 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001121 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001122 if (status < 0)
1123 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001124 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001125 if (status < 0)
1126 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001127 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001128 if (status < 0)
1129 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001130 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001131 if (status < 0)
1132 break;
1133 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1134 if (status < 0)
1135 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001136
1137 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001138 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001139 mutex_unlock(&state->mutex);
1140 return status;
1141}
1142
1143static int InitHI(struct drxk_state *state)
1144{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001145 dprintk(1, "\n");
1146
Oliver Endrissebc7de22011-07-03 13:49:44 -03001147 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001148 state->m_HICfgTimeout = 0x96FF;
1149 /* port/bridge/power down ctrl */
1150 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001151 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001152}
1153
1154static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1155{
1156 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001157 u16 sioPdrMclkCfg = 0;
1158 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001159
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001160 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001161 do {
1162 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001163 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001164 if (status < 0)
1165 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001166
1167 /* MPEG TS pad configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001168 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001169 if (status < 0)
1170 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001171
1172 if (mpegEnable == false) {
1173 /* Set MPEG TS pads to inputmode */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001174 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001175 if (status < 0)
1176 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001177 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001178 if (status < 0)
1179 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001180 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001181 if (status < 0)
1182 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001183 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001184 if (status < 0)
1185 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001186 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001187 if (status < 0)
1188 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001189 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001190 if (status < 0)
1191 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001192 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001193 if (status < 0)
1194 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001195 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001196 if (status < 0)
1197 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001198 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001199 if (status < 0)
1200 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001201 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001202 if (status < 0)
1203 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001204 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001205 if (status < 0)
1206 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001207 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001208 if (status < 0)
1209 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001210 } else {
1211 /* Enable MPEG output */
1212 sioPdrMdxCfg =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001213 ((state->m_TSDataStrength <<
1214 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001215 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03001216 SIO_PDR_MCLK_CFG_DRIVE__B) |
1217 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001218
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001219 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001220 if (status < 0)
1221 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001222 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001223 if (status < 0)
1224 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001225 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001226 if (status < 0)
1227 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001228 if (state->m_enableParallel == true) {
1229 /* paralel -> enable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001230 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001231 if (status < 0)
1232 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001233 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001234 if (status < 0)
1235 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001236 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001237 if (status < 0)
1238 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001239 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001240 if (status < 0)
1241 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001242 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001243 if (status < 0)
1244 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001245 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001246 if (status < 0)
1247 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001248 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001249 if (status < 0)
1250 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001251 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001252 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1253 SIO_PDR_MD0_CFG_DRIVE__B)
1254 | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001255 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001256 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001257 if (status < 0)
1258 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001259 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001260 if (status < 0)
1261 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001262 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001263 if (status < 0)
1264 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001265 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001266 if (status < 0)
1267 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001268 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001269 if (status < 0)
1270 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001271 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001272 if (status < 0)
1273 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001274 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001275 if (status < 0)
1276 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001277 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001278 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001279 if (status < 0)
1280 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001281 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001282 if (status < 0)
1283 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001284 }
1285 /* Enable MB output over MPEG pads and ctl input */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001286 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001287 if (status < 0)
1288 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001289 /* Write nomagic word to enable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001290 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001291 if (status < 0)
1292 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001293 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001294 return status;
1295}
1296
1297static int MPEGTSDisable(struct drxk_state *state)
1298{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001299 dprintk(1, "\n");
1300
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001301 return MPEGTSConfigurePins(state, false);
1302}
1303
1304static int BLChainCmd(struct drxk_state *state,
1305 u16 romOffset, u16 nrOfElements, u32 timeOut)
1306{
1307 u16 blStatus = 0;
1308 int status;
1309 unsigned long end;
1310
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001311 dprintk(1, "\n");
1312
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001313 mutex_lock(&state->mutex);
1314 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001315 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001316 if (status < 0)
1317 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001318 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001319 if (status < 0)
1320 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001321 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001322 if (status < 0)
1323 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001324 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001325 if (status < 0)
1326 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001327 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001328
1329 do {
1330 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001331 status = read16(state, SIO_BL_STATUS__A, &blStatus);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001332 if (status < 0)
1333 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001334 } while ((blStatus == 0x1) &&
1335 ((time_is_after_jiffies(end))));
1336 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001337 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001338 mutex_unlock(&state->mutex);
1339 return -1;
1340 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001341 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001342 mutex_unlock(&state->mutex);
1343 return status;
1344}
1345
1346
1347static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001348 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001349{
1350 const u8 *pSrc = pMCImage;
1351 u16 Flags;
1352 u16 Drain;
1353 u32 Address;
1354 u16 nBlocks;
1355 u16 BlockSize;
1356 u16 BlockCRC;
1357 u32 offset = 0;
1358 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001359 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001360
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001361 dprintk(1, "\n");
1362
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001363 /* down the drain (we don care about MAGIC_WORD) */
1364 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001365 pSrc += sizeof(u16);
1366 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001367 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001368 pSrc += sizeof(u16);
1369 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001370
1371 for (i = 0; i < nBlocks; i += 1) {
1372 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001373 (pSrc[2] << 8) | pSrc[3];
1374 pSrc += sizeof(u32);
1375 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001376
1377 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001378 pSrc += sizeof(u16);
1379 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001380
1381 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001382 pSrc += sizeof(u16);
1383 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001384
1385 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001386 pSrc += sizeof(u16);
1387 offset += sizeof(u16);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001388 status = write_block(state, Address, BlockSize, pSrc);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001389 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001390 break;
1391 pSrc += BlockSize;
1392 offset += BlockSize;
1393 }
1394 return status;
1395}
1396
1397static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1398{
1399 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001400 u16 data = 0;
1401 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001402 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1403 unsigned long end;
1404
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001405 dprintk(1, "\n");
1406
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001407 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001408 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001409 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1410 }
1411
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001412 status = (read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001413
1414 if (data == desiredStatus) {
1415 /* tokenring already has correct status */
1416 return status;
1417 }
1418 /* Disable/enable dvbt tokenring bridge */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001419 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001420 write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001421
Oliver Endrissebc7de22011-07-03 13:49:44 -03001422 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001423 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001424 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001425 if (status < 0)
1426 break;
1427 } while ((data != desiredStatus) && ((time_is_after_jiffies(end))));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001428 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001429 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001430 return -1;
1431 }
1432 return status;
1433}
1434
1435static int MPEGTSStop(struct drxk_state *state)
1436{
1437 int status = 0;
1438 u16 fecOcSncMode = 0;
1439 u16 fecOcIprMode = 0;
1440
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001441 dprintk(1, "\n");
1442
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001443 do {
1444 /* Gracefull shutdown (byte boundaries) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001445 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001446 if (status < 0)
1447 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001448 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001449 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001450 if (status < 0)
1451 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001452
1453 /* Suppress MCLK during absence of data */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001454 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001455 if (status < 0)
1456 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001457 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001458 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001459 if (status < 0)
1460 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001461 } while (0);
1462 return status;
1463}
1464
1465static int scu_command(struct drxk_state *state,
1466 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001467 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001468{
1469#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1470#error DRXK register mapping no longer compatible with this routine!
1471#endif
1472 u16 curCmd = 0;
1473 int status;
1474 unsigned long end;
1475
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001476 dprintk(1, "\n");
1477
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001478 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1479 ((resultLen > 0) && (result == NULL)))
1480 return -1;
1481
1482 mutex_lock(&state->mutex);
1483 do {
1484 /* assume that the command register is ready
1485 since it is checked afterwards */
1486 u8 buffer[34];
1487 int cnt = 0, ii;
1488
Oliver Endrissebc7de22011-07-03 13:49:44 -03001489 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001490 buffer[cnt++] = (parameter[ii] & 0xFF);
1491 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1492 }
1493 buffer[cnt++] = (cmd & 0xFF);
1494 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1495
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001496 write_block(state, SCU_RAM_PARAM_0__A -
1497 (parameterLen - 1), cnt, buffer);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001498 /* Wait until SCU has processed command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001499 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001500 do {
1501 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001502 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001503 if (status < 0)
1504 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001505 } while (!(curCmd == DRX_SCU_READY)
1506 && (time_is_after_jiffies(end)));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001507 if (curCmd != DRX_SCU_READY) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001508 printk(KERN_ERR "drxk: SCU not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001509 mutex_unlock(&state->mutex);
1510 return -1;
1511 }
1512 /* read results */
1513 if ((resultLen > 0) && (result != NULL)) {
1514 s16 err;
1515 int ii;
1516
Oliver Endrissebc7de22011-07-03 13:49:44 -03001517 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001518 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001519 if (status < 0)
1520 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001521 }
1522
1523 /* Check if an error was reported by SCU */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001524 err = (s16) result[0];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001525
1526 /* check a few fixed error codes */
1527 if (err == SCU_RESULT_UNKSTD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001528 printk(KERN_ERR "drxk: SCU_RESULT_UNKSTD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001529 mutex_unlock(&state->mutex);
1530 return -1;
1531 } else if (err == SCU_RESULT_UNKCMD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001532 printk(KERN_ERR "drxk: SCU_RESULT_UNKCMD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001533 mutex_unlock(&state->mutex);
1534 return -1;
1535 }
1536 /* here it is assumed that negative means error,
1537 and positive no error */
1538 else if (err < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001539 printk(KERN_ERR "drxk: %s ERROR\n", __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001540 mutex_unlock(&state->mutex);
1541 return -1;
1542 }
1543 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001544 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001545 mutex_unlock(&state->mutex);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001546 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001547 printk(KERN_ERR "drxk: %s: status = %d\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001548
1549 return status;
1550}
1551
1552static int SetIqmAf(struct drxk_state *state, bool active)
1553{
1554 u16 data = 0;
1555 int status;
1556
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001557 dprintk(1, "\n");
1558
Oliver Endrissebc7de22011-07-03 13:49:44 -03001559 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001560 /* Configure IQM */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001561 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001562 if (status < 0)
1563 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001564 if (!active) {
1565 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1566 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1567 | IQM_AF_STDBY_STDBY_PD_STANDBY
1568 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
Oliver Endrissebc7de22011-07-03 13:49:44 -03001569 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1570 } else { /* active */
1571
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001572 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1573 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1574 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1575 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1576 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
Oliver Endrissebc7de22011-07-03 13:49:44 -03001577 );
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001578 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001579 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001580 if (status < 0)
1581 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001582 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001583 return status;
1584}
1585
Oliver Endrissebc7de22011-07-03 13:49:44 -03001586static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001587{
1588 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001589 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001590
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001591 dprintk(1, "\n");
1592
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001593 /* Check arguments */
1594 if (mode == NULL)
1595 return -1;
1596
1597 switch (*mode) {
1598 case DRX_POWER_UP:
1599 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1600 break;
1601 case DRXK_POWER_DOWN_OFDM:
1602 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1603 break;
1604 case DRXK_POWER_DOWN_CORE:
1605 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1606 break;
1607 case DRXK_POWER_DOWN_PLL:
1608 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1609 break;
1610 case DRX_POWER_DOWN:
1611 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1612 break;
1613 default:
1614 /* Unknow sleep mode */
1615 return -1;
1616 break;
1617 }
1618
1619 /* If already in requested power mode, do nothing */
1620 if (state->m_currentPowerMode == *mode)
1621 return 0;
1622
1623 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001624 if (state->m_currentPowerMode != DRX_POWER_UP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001625 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001626 status = PowerUpDevice(state);
1627 if (status < 0)
1628 break;
1629 status = DVBTEnableOFDMTokenRing(state, true);
1630 if (status < 0)
1631 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001632 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001633 }
1634
1635 if (*mode == DRX_POWER_UP) {
1636 /* Restore analog & pin configuartion */
1637 } else {
1638 /* Power down to requested mode */
1639 /* Backup some register settings */
1640 /* Set pins with possible pull-ups connected
1641 to them in input mode */
1642 /* Analog power down */
1643 /* ADC power down */
1644 /* Power down device */
1645 /* stop all comm_exec */
1646 /* Stop and power down previous standard */
1647 do {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001648 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001649 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001650 status = MPEGTSStop(state);
1651 if (status < 0)
1652 break;
1653 status = PowerDownDVBT(state, false);
1654 if (status < 0)
1655 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001656 break;
1657 case OM_QAM_ITU_A:
1658 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001659 status = MPEGTSStop(state);
1660 if (status < 0)
1661 break;
1662 status = PowerDownQAM(state);
1663 if (status < 0)
1664 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001665 break;
1666 default:
1667 break;
1668 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001669 status = DVBTEnableOFDMTokenRing(state, false);
1670 if (status < 0)
1671 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001672 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001673 if (status < 0)
1674 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001675 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001676 if (status < 0)
1677 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001678
Oliver Endrissebc7de22011-07-03 13:49:44 -03001679 if (*mode != DRXK_POWER_DOWN_OFDM) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001680 state->m_HICfgCtrl |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03001681 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001682 status = HI_CfgCommand(state);
1683 if (status < 0)
1684 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001685 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001686 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001687 }
1688 state->m_currentPowerMode = *mode;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001689 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001690}
1691
1692static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1693{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001694 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001695 u16 cmdResult = 0;
1696 u16 data = 0;
1697 int status;
1698
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001699 dprintk(1, "\n");
1700
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001701 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001702 status = read16(state, SCU_COMM_EXEC__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001703 if (status < 0)
1704 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001705 if (data == SCU_COMM_EXEC_ACTIVE) {
1706 /* Send OFDM stop command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001707 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
1708 if (status < 0)
1709 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001710 /* Send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001711 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1712 if (status < 0)
1713 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001714 }
1715
1716 /* Reset datapath for OFDM, processors first */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001717 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001718 if (status < 0)
1719 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001720 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001721 if (status < 0)
1722 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001723 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001724 if (status < 0)
1725 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001726
1727 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001728 status = SetIqmAf(state, false);
1729 if (status < 0)
1730 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001731
1732 /* powerdown to OFDM mode */
1733 if (setPowerMode) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001734 status = CtrlPowerMode(state, &powerMode);
1735 if (status < 0)
1736 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001737 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001738 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001739 return status;
1740}
1741
Oliver Endrissebc7de22011-07-03 13:49:44 -03001742static int SetOperationMode(struct drxk_state *state,
1743 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001744{
1745 int status = 0;
1746
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001747 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001748 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001749 Stop and power down previous standard
1750 TODO investigate total power down instead of partial
1751 power down depending on "previous" standard.
1752 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001753 do {
1754 /* disable HW lock indicator */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001755 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001756 if (status < 0)
1757 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001758
1759 if (state->m_OperationMode != oMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001760 switch (state->m_OperationMode) {
1761 /* OM_NONE was added for start up */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001762 case OM_NONE:
1763 break;
1764 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001765 status = MPEGTSStop(state);
1766 if (status < 0)
1767 break;
1768 status = PowerDownDVBT(state, true);
1769 if (status < 0)
1770 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001771 state->m_OperationMode = OM_NONE;
1772 break;
1773 case OM_QAM_ITU_B:
1774 status = -1;
1775 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001776 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001777 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001778 status = MPEGTSStop(state);
1779 if (status < 0)
1780 break;
1781 status = PowerDownQAM(state);
1782 if (status < 0)
1783 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001784 state->m_OperationMode = OM_NONE;
1785 break;
1786 default:
1787 status = -1;
1788 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001789 status = status;
1790 if (status < 0)
1791 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001792
1793 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001794 Power up new standard
1795 */
1796 switch (oMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001797 case OM_DVBT:
1798 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001799 status = SetDVBTStandard(state, oMode);
1800 if (status < 0)
1801 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001802 break;
1803 case OM_QAM_ITU_B:
1804 status = -1;
1805 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001806 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001807 case OM_QAM_ITU_C:
1808 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001809 status = SetQAMStandard(state, oMode);
1810 if (status < 0)
1811 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001812 break;
1813 default:
1814 status = -1;
1815 }
1816 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001817 status = status;
1818 if (status < 0)
1819 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001820 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001821 return 0;
1822}
1823
1824static int Start(struct drxk_state *state, s32 offsetFreq,
1825 s32 IntermediateFrequency)
1826{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001827 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001828
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001829 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001830 do {
1831 u16 IFreqkHz;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001832 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001833
1834 if (state->m_DrxkState != DRXK_STOPPED &&
1835 state->m_DrxkState != DRXK_DTV_STARTED) {
1836 status = -1;
1837 break;
1838 }
1839 state->m_bMirrorFreqSpect =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001840 (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001841
1842 if (IntermediateFrequency < 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001843 state->m_bMirrorFreqSpect =
1844 !state->m_bMirrorFreqSpect;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001845 IntermediateFrequency = -IntermediateFrequency;
1846 }
1847
Oliver Endrissebc7de22011-07-03 13:49:44 -03001848 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001849 case OM_QAM_ITU_A:
1850 case OM_QAM_ITU_C:
1851 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001852 status = SetQAM(state, IFreqkHz, OffsetkHz);
1853 if (status < 0)
1854 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001855 state->m_DrxkState = DRXK_DTV_STARTED;
1856 break;
1857 case OM_DVBT:
1858 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001859 status = MPEGTSStop(state);
1860 if (status < 0)
1861 break;
1862 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1863 if (status < 0)
1864 break;
1865 status = DVBTStart(state);
1866 if (status < 0)
1867 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001868 state->m_DrxkState = DRXK_DTV_STARTED;
1869 break;
1870 default:
1871 break;
1872 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001873 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001874 return status;
1875}
1876
1877static int ShutDown(struct drxk_state *state)
1878{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001879 dprintk(1, "\n");
1880
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001881 MPEGTSStop(state);
1882 return 0;
1883}
1884
Oliver Endrissebc7de22011-07-03 13:49:44 -03001885static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1886 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001887{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001888 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001889
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001890 dprintk(1, "\n");
1891
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001892 if (pLockStatus == NULL)
1893 return -1;
1894
1895 *pLockStatus = NOT_LOCKED;
1896
1897 /* define the SCU command code */
1898 switch (state->m_OperationMode) {
1899 case OM_QAM_ITU_A:
1900 case OM_QAM_ITU_B:
1901 case OM_QAM_ITU_C:
1902 status = GetQAMLockStatus(state, pLockStatus);
1903 break;
1904 case OM_DVBT:
1905 status = GetDVBTLockStatus(state, pLockStatus);
1906 break;
1907 default:
1908 break;
1909 }
1910 return status;
1911}
1912
1913static int MPEGTSStart(struct drxk_state *state)
1914{
1915 int status = 0;
1916
1917 u16 fecOcSncMode = 0;
1918
1919 do {
1920 /* Allow OC to sync again */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001921 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001922 if (status < 0)
1923 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001924 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001925 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001926 if (status < 0)
1927 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001928 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001929 if (status < 0)
1930 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001931 } while (0);
1932 return status;
1933}
1934
1935static int MPEGTSDtoInit(struct drxk_state *state)
1936{
1937 int status = -1;
1938
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001939 dprintk(1, "\n");
1940
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001941 do {
1942 /* Rate integration settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001943 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001944 if (status < 0)
1945 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001946 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001947 if (status < 0)
1948 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001949 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001950 if (status < 0)
1951 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001952 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001953 if (status < 0)
1954 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001955 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001956 if (status < 0)
1957 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001958 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001959 if (status < 0)
1960 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001961 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001962 if (status < 0)
1963 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001964 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001965 if (status < 0)
1966 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001967
1968 /* Additional configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001969 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001970 if (status < 0)
1971 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001972 status = write16(state, FEC_OC_SNC_LWM__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001973 if (status < 0)
1974 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001975 status = write16(state, FEC_OC_SNC_HWM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001976 if (status < 0)
1977 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001978 } while (0);
1979 return status;
1980}
1981
Oliver Endrissebc7de22011-07-03 13:49:44 -03001982static int MPEGTSDtoSetup(struct drxk_state *state,
1983 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001984{
1985 int status = -1;
1986
Oliver Endrissebc7de22011-07-03 13:49:44 -03001987 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
1988 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
1989 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
1990 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
1991 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
1992 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
1993 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001994 u16 fecOcTmdMode = 0;
1995 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001996 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001997 bool staticCLK = false;
1998
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001999 dprintk(1, "\n");
2000
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002001 do {
2002 /* Check insertion of the Reed-Solomon parity bytes */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002003 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002004 if (status < 0)
2005 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002006 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002007 if (status < 0)
2008 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002009 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002010 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2011 if (state->m_insertRSByte == true) {
2012 /* enable parity symbol forward */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002013 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002014 /* MVAL disable during parity bytes */
2015 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2016 /* TS burst length to 204 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002017 fecOcDtoBurstLen = 204;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002018 }
2019
2020 /* Check serial or parrallel output */
2021 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2022 if (state->m_enableParallel == false) {
2023 /* MPEG data output is serial -> set ipr_mode[0] */
2024 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2025 }
2026
2027 switch (oMode) {
2028 case OM_DVBT:
2029 maxBitRate = state->m_DVBTBitrate;
2030 fecOcTmdMode = 3;
2031 fecOcRcnCtlRate = 0xC00000;
2032 staticCLK = state->m_DVBTStaticCLK;
2033 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002034 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002035 case OM_QAM_ITU_C:
2036 fecOcTmdMode = 0x0004;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002037 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002038 maxBitRate = state->m_DVBCBitrate;
2039 staticCLK = state->m_DVBCStaticCLK;
2040 break;
2041 default:
2042 status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002043 } /* switch (standard) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002044 status = status;
2045 if (status < 0)
2046 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002047
2048 /* Configure DTO's */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002049 if (staticCLK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002050 u32 bitRate = 0;
2051
2052 /* Rational DTO for MCLK source (static MCLK rate),
2053 Dynamic DTO for optimal grouping
2054 (avoid intra-packet gaps),
2055 DTO offset enable to sync TS burst with MSTRT */
2056 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2057 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2058 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2059 FEC_OC_FCT_MODE_VIRT_ENA__M);
2060
2061 /* Check user defined bitrate */
2062 bitRate = maxBitRate;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002063 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002064 bitRate = 75900000UL;
2065 }
2066 /* Rational DTO period:
2067 dto_period = (Fsys / bitrate) - 2
2068
2069 Result should be floored,
2070 to make sure >= requested bitrate
Oliver Endrissebc7de22011-07-03 13:49:44 -03002071 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002072 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2073 * 1000) / bitRate);
2074 if (fecOcDtoPeriod <= 2)
2075 fecOcDtoPeriod = 0;
2076 else
2077 fecOcDtoPeriod -= 2;
2078 fecOcTmdIntUpdRate = 8;
2079 } else {
2080 /* (commonAttr->staticCLK == false) => dynamic mode */
2081 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2082 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2083 fecOcTmdIntUpdRate = 5;
2084 }
2085
2086 /* Write appropriate registers with requested configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002087 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002088 if (status < 0)
2089 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002090 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002091 if (status < 0)
2092 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002093 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002094 if (status < 0)
2095 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002096 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002097 if (status < 0)
2098 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002099 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002100 if (status < 0)
2101 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002102 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002103 if (status < 0)
2104 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002105
2106 /* Rate integration settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002107 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002108 if (status < 0)
2109 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002110 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002111 if (status < 0)
2112 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002113 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002114 if (status < 0)
2115 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002116 } while (0);
2117 return status;
2118}
2119
2120static int MPEGTSConfigurePolarity(struct drxk_state *state)
2121{
2122 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002123 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002124
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002125 dprintk(1, "\n");
2126
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002127 /* Data mask for the output data byte */
2128 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002129 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2130 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2131 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2132 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002133
2134 /* Control selective inversion of output bits */
2135 fecOcRegIprInvert &= (~(InvertDataMask));
2136 if (state->m_invertDATA == true)
2137 fecOcRegIprInvert |= InvertDataMask;
2138 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2139 if (state->m_invertERR == true)
2140 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2141 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2142 if (state->m_invertSTR == true)
2143 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2144 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2145 if (state->m_invertVAL == true)
2146 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2147 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2148 if (state->m_invertCLK == true)
2149 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002150 status = write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002151 return status;
2152}
2153
2154#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2155
2156static int SetAgcRf(struct drxk_state *state,
2157 struct SCfgAgc *pAgcCfg, bool isDTV)
2158{
2159 int status = 0;
2160 struct SCfgAgc *pIfAgcSettings;
2161
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002162 dprintk(1, "\n");
2163
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002164 if (pAgcCfg == NULL)
2165 return -1;
2166
2167 do {
2168 u16 data = 0;
2169
2170 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002171 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002172
2173 /* Enable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002174 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002175 if (status < 0)
2176 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002177 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002178 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002179 if (status < 0)
2180 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002181
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002182 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002183 if (status < 0)
2184 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002185
2186 /* Enable SCU RF AGC loop */
2187 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2188
2189 /* Polarity */
2190 if (state->m_RfAgcPol)
2191 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2192 else
2193 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002194 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002195 if (status < 0)
2196 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002197
2198 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002199 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002200 if (status < 0)
2201 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002202
2203 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2204 data |= (~(pAgcCfg->speed <<
2205 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2206 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2207
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002208 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002209 if (status < 0)
2210 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002211
2212 if (IsDVBT(state))
2213 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2214 else if (IsQAM(state))
2215 pIfAgcSettings = &state->m_qamIfAgcCfg;
2216 else
2217 pIfAgcSettings = &state->m_atvIfAgcCfg;
2218 if (pIfAgcSettings == NULL)
2219 return -1;
2220
2221 /* Set TOP, only if IF-AGC is in AUTO mode */
2222 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002223 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002224 if (status < 0)
2225 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002226
2227 /* Cut-Off current */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002228 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002229 if (status < 0)
2230 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002231
2232 /* Max. output level */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002233 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002234 if (status < 0)
2235 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002236
2237 break;
2238
2239 case DRXK_AGC_CTRL_USER:
2240 /* Enable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002241 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002242 if (status < 0)
2243 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002244 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002245 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002246 if (status < 0)
2247 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002248
2249 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002250 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002251 if (status < 0)
2252 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002253 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2254 if (state->m_RfAgcPol)
2255 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2256 else
2257 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002258 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002259 if (status < 0)
2260 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002261
2262 /* SCU c.o.c. to 0, enabling full control range */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002263 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002264 if (status < 0)
2265 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002266
2267 /* Write value to output pin */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002268 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002269 if (status < 0)
2270 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002271 break;
2272
Oliver Endrissebc7de22011-07-03 13:49:44 -03002273 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002274 /* Disable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002275 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002276 if (status < 0)
2277 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002278 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002279 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002280 if (status < 0)
2281 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002282
2283 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002284 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002285 if (status < 0)
2286 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002287 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002288 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002289 if (status < 0)
2290 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002291 break;
2292
2293 default:
2294 return -1;
2295
Oliver Endrissebc7de22011-07-03 13:49:44 -03002296 } /* switch (agcsettings->ctrlMode) */
2297 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002298 return status;
2299}
2300
2301#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2302
Oliver Endrissebc7de22011-07-03 13:49:44 -03002303static int SetAgcIf(struct drxk_state *state,
2304 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002305{
2306 u16 data = 0;
2307 int status = 0;
2308 struct SCfgAgc *pRfAgcSettings;
2309
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002310 dprintk(1, "\n");
2311
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002312 do {
2313 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002314 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002315
2316 /* Enable IF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002317 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002318 if (status < 0)
2319 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002320 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002321 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002322 if (status < 0)
2323 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002324
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002325 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002326 if (status < 0)
2327 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002328
2329 /* Enable SCU IF AGC loop */
2330 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2331
2332 /* Polarity */
2333 if (state->m_IfAgcPol)
2334 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2335 else
2336 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002337 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002338 if (status < 0)
2339 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002340
2341 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002342 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002343 if (status < 0)
2344 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002345 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2346 data |= (~(pAgcCfg->speed <<
2347 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2348 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2349
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002350 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002351 if (status < 0)
2352 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002353
2354 if (IsQAM(state))
2355 pRfAgcSettings = &state->m_qamRfAgcCfg;
2356 else
2357 pRfAgcSettings = &state->m_atvRfAgcCfg;
2358 if (pRfAgcSettings == NULL)
2359 return -1;
2360 /* Restore TOP */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002361 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002362 if (status < 0)
2363 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002364 break;
2365
Oliver Endrissebc7de22011-07-03 13:49:44 -03002366 case DRXK_AGC_CTRL_USER:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002367
2368 /* Enable IF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002369 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002370 if (status < 0)
2371 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002372 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002373 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002374 if (status < 0)
2375 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002376
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002377 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002378 if (status < 0)
2379 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002380
2381 /* Disable SCU IF AGC loop */
2382 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2383
2384 /* Polarity */
2385 if (state->m_IfAgcPol)
2386 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2387 else
2388 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002389 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002390 if (status < 0)
2391 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002392
2393 /* Write value to output pin */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002394 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002395 if (status < 0)
2396 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002397 break;
2398
Oliver Endrissebc7de22011-07-03 13:49:44 -03002399 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002400
2401 /* Disable If AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002402 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002403 if (status < 0)
2404 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002405 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002406 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002407 if (status < 0)
2408 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002409
2410 /* Disable SCU IF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002411 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002412 if (status < 0)
2413 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002414 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002415 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002416 if (status < 0)
2417 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002418 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002419 } /* switch (agcSettingsIf->ctrlMode) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002420
2421 /* always set the top to support
2422 configurations without if-loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002423 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002424 if (status < 0)
2425 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002426
2427
Oliver Endrissebc7de22011-07-03 13:49:44 -03002428 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002429 return status;
2430}
2431
2432static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2433{
2434 u16 agcDacLvl;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002435 int status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002436
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002437 dprintk(1, "\n");
2438
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002439 *pValue = 0;
2440
Oliver Endrissebc7de22011-07-03 13:49:44 -03002441 if (status == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002442 u16 Level = 0;
2443 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2444 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2445 if (Level < 14000)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002446 *pValue = (14000 - Level) / 4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002447 else
2448 *pValue = 0;
2449 }
2450 return status;
2451}
2452
Oliver Endrissebc7de22011-07-03 13:49:44 -03002453static int GetQAMSignalToNoise(struct drxk_state *state,
2454 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002455{
2456 int status = 0;
2457
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002458 dprintk(1, "\n");
2459
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002460 do {
2461 /* MER calculation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002462 u16 qamSlErrPower = 0; /* accum. error between
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002463 raw and sliced symbols */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002464 u32 qamSlSigPower = 0; /* used for MER, depends of
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002465 QAM constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002466 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002467
2468 /* get the register value needed for MER */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002469 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002470 if (status < 0)
2471 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002472
Oliver Endrissebc7de22011-07-03 13:49:44 -03002473 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002474 case QAM_16:
2475 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2476 break;
2477 case QAM_32:
2478 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2479 break;
2480 case QAM_64:
2481 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2482 break;
2483 case QAM_128:
2484 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2485 break;
2486 default:
2487 case QAM_256:
2488 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2489 break;
2490 }
2491
2492 if (qamSlErrPower > 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002493 qamSlMer = Log10Times100(qamSlSigPower) -
2494 Log10Times100((u32) qamSlErrPower);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002495 }
2496 *pSignalToNoise = qamSlMer;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002497 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002498 return status;
2499}
2500
Oliver Endrissebc7de22011-07-03 13:49:44 -03002501static int GetDVBTSignalToNoise(struct drxk_state *state,
2502 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002503{
2504 int status = 0;
2505
Oliver Endrissebc7de22011-07-03 13:49:44 -03002506 u16 regData = 0;
2507 u32 EqRegTdSqrErrI = 0;
2508 u32 EqRegTdSqrErrQ = 0;
2509 u16 EqRegTdSqrErrExp = 0;
2510 u16 EqRegTdTpsPwrOfs = 0;
2511 u16 EqRegTdReqSmbCnt = 0;
2512 u32 tpsCnt = 0;
2513 u32 SqrErrIQ = 0;
2514 u32 a = 0;
2515 u32 b = 0;
2516 u32 c = 0;
2517 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002518 u16 transmissionParams = 0;
2519
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002520 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002521 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002522 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002523 if (status < 0)
2524 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002525 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002526 if (status < 0)
2527 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002528 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002529 if (status < 0)
2530 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002531 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002532 if (status < 0)
2533 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002534 /* Extend SQR_ERR_I operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002535 EqRegTdSqrErrI = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002536 if ((EqRegTdSqrErrExp > 11) &&
2537 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2538 EqRegTdSqrErrI += 0x00010000UL;
2539 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002540 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002541 if (status < 0)
2542 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002543 /* Extend SQR_ERR_Q operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002544 EqRegTdSqrErrQ = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002545 if ((EqRegTdSqrErrExp > 11) &&
2546 (EqRegTdSqrErrQ < 0x00000FFFUL))
2547 EqRegTdSqrErrQ += 0x00010000UL;
2548
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002549 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002550 if (status < 0)
2551 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002552
2553 /* Check input data for MER */
2554
2555 /* MER calculation (in 0.1 dB) without math.h */
2556 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2557 iMER = 0;
2558 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2559 /* No error at all, this must be the HW reset value
2560 * Apparently no first measurement yet
2561 * Set MER to 0.0 */
2562 iMER = 0;
2563 } else {
2564 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03002565 EqRegTdSqrErrExp;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002566 if ((transmissionParams &
2567 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2568 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2569 tpsCnt = 17;
2570 else
2571 tpsCnt = 68;
2572
2573 /* IMER = 100 * log10 (x)
2574 where x = (EqRegTdTpsPwrOfs^2 *
2575 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2576
2577 => IMER = a + b -c
2578 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2579 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2580 c = 100 * log10 (SqrErrIQ)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002581 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002582
2583 /* log(x) x = 9bits * 9bits->18 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002584 a = Log10Times100(EqRegTdTpsPwrOfs *
2585 EqRegTdTpsPwrOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002586 /* log(x) x = 16bits * 7bits->23 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002587 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002588 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2589 c = Log10Times100(SqrErrIQ);
2590
2591 iMER = a + b;
2592 /* No negative MER, clip to zero */
2593 if (iMER > c)
2594 iMER -= c;
2595 else
2596 iMER = 0;
2597 }
2598 *pSignalToNoise = iMER;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002599 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002600
2601 return status;
2602}
2603
2604static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2605{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002606 dprintk(1, "\n");
2607
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002608 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002609 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002610 case OM_DVBT:
2611 return GetDVBTSignalToNoise(state, pSignalToNoise);
2612 case OM_QAM_ITU_A:
2613 case OM_QAM_ITU_C:
2614 return GetQAMSignalToNoise(state, pSignalToNoise);
2615 default:
2616 break;
2617 }
2618 return 0;
2619}
2620
2621#if 0
2622static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2623{
2624 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2625 int status = 0;
2626
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002627 dprintk(1, "\n");
2628
Oliver Endrissebc7de22011-07-03 13:49:44 -03002629 static s32 QE_SN[] = {
2630 51, /* QPSK 1/2 */
2631 69, /* QPSK 2/3 */
2632 79, /* QPSK 3/4 */
2633 89, /* QPSK 5/6 */
2634 97, /* QPSK 7/8 */
2635 108, /* 16-QAM 1/2 */
2636 131, /* 16-QAM 2/3 */
2637 146, /* 16-QAM 3/4 */
2638 156, /* 16-QAM 5/6 */
2639 160, /* 16-QAM 7/8 */
2640 165, /* 64-QAM 1/2 */
2641 187, /* 64-QAM 2/3 */
2642 202, /* 64-QAM 3/4 */
2643 216, /* 64-QAM 5/6 */
2644 225, /* 64-QAM 7/8 */
2645 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002646
2647 *pQuality = 0;
2648
2649 do {
2650 s32 SignalToNoise = 0;
2651 u16 Constellation = 0;
2652 u16 CodeRate = 0;
2653 u32 SignalToNoiseRel;
2654 u32 BERQuality;
2655
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002656 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2657 if (status < 0)
2658 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002659 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002660 if (status < 0)
2661 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002662 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2663
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002664 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002665 if (status < 0)
2666 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002667 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2668
2669 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2670 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2671 break;
2672 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002673 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002674 BERQuality = 100;
2675
Oliver Endrissebc7de22011-07-03 13:49:44 -03002676 if (SignalToNoiseRel < -70)
2677 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002678 else if (SignalToNoiseRel < 30)
2679 *pQuality = ((SignalToNoiseRel + 70) *
2680 BERQuality) / 100;
2681 else
2682 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002683 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002684 return 0;
2685};
2686
Oliver Endrissebc7de22011-07-03 13:49:44 -03002687static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002688{
2689 int status = 0;
2690 *pQuality = 0;
2691
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002692 dprintk(1, "\n");
2693
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002694 do {
2695 u32 SignalToNoise = 0;
2696 u32 BERQuality = 100;
2697 u32 SignalToNoiseRel = 0;
2698
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002699 status = GetQAMSignalToNoise(state, &SignalToNoise);
2700 if (status < 0)
2701 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002702
Oliver Endrissebc7de22011-07-03 13:49:44 -03002703 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002704 case QAM_16:
2705 SignalToNoiseRel = SignalToNoise - 200;
2706 break;
2707 case QAM_32:
2708 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002709 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002710 case QAM_64:
2711 SignalToNoiseRel = SignalToNoise - 260;
2712 break;
2713 case QAM_128:
2714 SignalToNoiseRel = SignalToNoise - 290;
2715 break;
2716 default:
2717 case QAM_256:
2718 SignalToNoiseRel = SignalToNoise - 320;
2719 break;
2720 }
2721
2722 if (SignalToNoiseRel < -70)
2723 *pQuality = 0;
2724 else if (SignalToNoiseRel < 30)
2725 *pQuality = ((SignalToNoiseRel + 70) *
2726 BERQuality) / 100;
2727 else
2728 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002729 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002730
2731 return status;
2732}
2733
2734static int GetQuality(struct drxk_state *state, s32 *pQuality)
2735{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002736 dprintk(1, "\n");
2737
Oliver Endrissebc7de22011-07-03 13:49:44 -03002738 switch (state->m_OperationMode) {
2739 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002740 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002741 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002742 return GetDVBCQuality(state, pQuality);
2743 default:
2744 break;
2745 }
2746
2747 return 0;
2748}
2749#endif
2750
2751/* Free data ram in SIO HI */
2752#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2753#define SIO_HI_RA_RAM_USR_END__A 0x420060
2754
2755#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2756#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2757#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2758#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2759
2760#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2761#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2762#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2763
2764static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2765{
2766 int status;
2767
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002768 dprintk(1, "\n");
2769
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002770 if (state->m_DrxkState == DRXK_UNINITIALIZED)
2771 return -1;
2772 if (state->m_DrxkState == DRXK_POWERED_DOWN)
2773 return -1;
2774
2775 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002776 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002777 if (status < 0)
2778 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002779 if (bEnableBridge) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002780 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002781 if (status < 0)
2782 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002783 } else {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002784 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002785 if (status < 0)
2786 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002787 }
2788
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002789 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2790 if (status < 0)
2791 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002792 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002793 return status;
2794}
2795
Oliver Endrissebc7de22011-07-03 13:49:44 -03002796static int SetPreSaw(struct drxk_state *state,
2797 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002798{
2799 int status;
2800
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002801 dprintk(1, "\n");
2802
Oliver Endrissebc7de22011-07-03 13:49:44 -03002803 if ((pPreSawCfg == NULL)
2804 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002805 return -1;
2806
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002807 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002808 return status;
2809}
2810
2811static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002812 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002813{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002814 u16 blStatus = 0;
2815 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2816 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2817 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002818 unsigned long end;
2819
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002820 dprintk(1, "\n");
2821
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002822 mutex_lock(&state->mutex);
2823 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002824 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002825 if (status < 0)
2826 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002827 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002828 if (status < 0)
2829 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002830 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002831 if (status < 0)
2832 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002833 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002834 if (status < 0)
2835 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002836 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002837 if (status < 0)
2838 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002839 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002840 if (status < 0)
2841 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002842
Oliver Endrissebc7de22011-07-03 13:49:44 -03002843 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002844 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002845 status = read16(state, SIO_BL_STATUS__A, &blStatus);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002846 if (status < 0)
2847 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002848 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002849 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03002850 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002851 mutex_unlock(&state->mutex);
2852 return -1;
2853 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03002854 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002855 mutex_unlock(&state->mutex);
2856 return status;
2857
2858}
2859
Oliver Endrissebc7de22011-07-03 13:49:44 -03002860static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002861{
2862 u16 data = 0;
2863 int status;
2864
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002865 dprintk(1, "\n");
2866
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002867 do {
2868 /* Start measurement */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002869 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002870 if (status < 0)
2871 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002872 status = write16(state, IQM_AF_START_LOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002873 if (status < 0)
2874 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002875
2876 *count = 0;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002877 status = read16(state, IQM_AF_PHASE0__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002878 if (status < 0)
2879 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002880 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002881 *count = *count + 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002882 status = read16(state, IQM_AF_PHASE1__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002883 if (status < 0)
2884 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002885 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002886 *count = *count + 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002887 status = read16(state, IQM_AF_PHASE2__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002888 if (status < 0)
2889 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002890 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002891 *count = *count + 1;
2892 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002893 return status;
2894}
2895
2896static int ADCSynchronization(struct drxk_state *state)
2897{
2898 u16 count = 0;
2899 int status;
2900
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002901 dprintk(1, "\n");
2902
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002903 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002904 status = ADCSyncMeasurement(state, &count);
2905 if (status < 0)
2906 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002907
Oliver Endrissebc7de22011-07-03 13:49:44 -03002908 if (count == 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002909 /* Try sampling on a diffrent edge */
2910 u16 clkNeg = 0;
2911
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002912 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002913 if (status < 0)
2914 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002915 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002916 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2917 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2918 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002919 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002920 } else {
2921 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2922 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002923 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002924 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002925 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002926 if (status < 0)
2927 break;
2928 status = ADCSyncMeasurement(state, &count);
2929 if (status < 0)
2930 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002931 }
2932
2933 if (count < 2)
2934 status = -1;
2935 } while (0);
2936 return status;
2937}
2938
2939static int SetFrequencyShifter(struct drxk_state *state,
2940 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002941 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002942{
2943 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002944 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002945 u32 fmFrequencyShift = 0;
2946 bool tunerMirror = !state->m_bMirrorFreqSpect;
2947 u32 adcFreq;
2948 bool adcFlip;
2949 int status;
2950 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002951 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002952 u32 frequencyShift;
2953 bool imageToSelect;
2954
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002955 dprintk(1, "\n");
2956
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002957 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03002958 Program frequency shifter
2959 No need to account for mirroring on RF
2960 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002961 if (isDTV) {
2962 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
2963 (state->m_OperationMode == OM_QAM_ITU_C) ||
2964 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03002965 selectPosImage = true;
2966 else
2967 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002968 }
2969 if (tunerMirror)
2970 /* tuner doesn't mirror */
2971 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03002972 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002973 else
2974 /* tuner mirrors */
2975 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002976 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002977 if (ifFreqActual > samplingFrequency / 2) {
2978 /* adc mirrors */
2979 adcFreq = samplingFrequency - ifFreqActual;
2980 adcFlip = true;
2981 } else {
2982 /* adc doesn't mirror */
2983 adcFreq = ifFreqActual;
2984 adcFlip = false;
2985 }
2986
2987 frequencyShift = adcFreq;
2988 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03002989 adcFlip ^ selectPosImage;
2990 state->m_IqmFsRateOfs =
2991 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002992
2993 if (imageToSelect)
2994 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
2995
2996 /* Program frequency shifter with tuner offset compensation */
2997 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002998 status = write32(state, IQM_FS_RATE_OFS_LO__A,
2999 state->m_IqmFsRateOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003000 return status;
3001}
3002
3003static int InitAGC(struct drxk_state *state, bool isDTV)
3004{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003005 u16 ingainTgt = 0;
3006 u16 ingainTgtMin = 0;
3007 u16 ingainTgtMax = 0;
3008 u16 clpCyclen = 0;
3009 u16 clpSumMin = 0;
3010 u16 clpDirTo = 0;
3011 u16 snsSumMin = 0;
3012 u16 snsSumMax = 0;
3013 u16 clpSumMax = 0;
3014 u16 snsDirTo = 0;
3015 u16 kiInnergainMin = 0;
3016 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003017 u16 ifIaccuHiTgtMin = 0;
3018 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003019 u16 data = 0;
3020 u16 fastClpCtrlDelay = 0;
3021 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003022 int status = 0;
3023
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003024 dprintk(1, "\n");
3025
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003026 do {
3027 /* Common settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003028 snsSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003029 ifIaccuHiTgtMin = 2047;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003030 clpCyclen = 500;
3031 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003032
3033 if (IsQAM(state)) {
3034 /* Standard specific settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003035 clpSumMin = 8;
3036 clpDirTo = (u16) -9;
3037 clpCtrlMode = 0;
3038 snsSumMin = 8;
3039 snsDirTo = (u16) -9;
3040 kiInnergainMin = (u16) -1030;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003041 } else
3042 status = -1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003043 status = (status);
3044 if (status < 0)
3045 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003046 if (IsQAM(state)) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003047 ifIaccuHiTgtMax = 0x2380;
3048 ifIaccuHiTgt = 0x2380;
3049 ingainTgtMin = 0x0511;
3050 ingainTgt = 0x0511;
3051 ingainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003052 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003053 state->m_qamIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003054 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003055 ifIaccuHiTgtMax = 0x1200;
3056 ifIaccuHiTgt = 0x1200;
3057 ingainTgtMin = 13424;
3058 ingainTgt = 13424;
3059 ingainTgtMax = 30000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003060 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003061 state->m_dvbtIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003062 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003063 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003064 if (status < 0)
3065 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003066
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003067 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003068 if (status < 0)
3069 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003070 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003071 if (status < 0)
3072 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003073 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003074 if (status < 0)
3075 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003076 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003077 if (status < 0)
3078 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003079 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003080 if (status < 0)
3081 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003082 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003083 if (status < 0)
3084 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003085 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003086 if (status < 0)
3087 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003088 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003089 if (status < 0)
3090 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003091 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003092 if (status < 0)
3093 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003094 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003095 if (status < 0)
3096 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003097 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003098 if (status < 0)
3099 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003100 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003101 if (status < 0)
3102 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003103
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003104 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003105 if (status < 0)
3106 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003107 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003108 if (status < 0)
3109 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003110 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003111 if (status < 0)
3112 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003113
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003114 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003115 if (status < 0)
3116 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003117 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003118 if (status < 0)
3119 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003120 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003121 if (status < 0)
3122 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003123
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003124 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003125 if (status < 0)
3126 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003127 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003128 if (status < 0)
3129 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003130 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003131 if (status < 0)
3132 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003133 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003134 if (status < 0)
3135 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003136 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003137 if (status < 0)
3138 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003139 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003140 if (status < 0)
3141 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003142 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003143 if (status < 0)
3144 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003145 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003146 if (status < 0)
3147 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003148 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003149 if (status < 0)
3150 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003151 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003152 if (status < 0)
3153 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003154 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003155 if (status < 0)
3156 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003157 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003158 if (status < 0)
3159 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003160 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003161 if (status < 0)
3162 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003163 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003164 if (status < 0)
3165 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003166 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003167 if (status < 0)
3168 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003169 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003170 if (status < 0)
3171 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003172 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003173 if (status < 0)
3174 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003175 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003176 if (status < 0)
3177 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003178 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003179 if (status < 0)
3180 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003181
3182 /* Initialize inner-loop KI gain factors */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003183 status = read16(state, SCU_RAM_AGC_KI__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003184 if (status < 0)
3185 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003186 if (IsQAM(state)) {
3187 data = 0x0657;
3188 data &= ~SCU_RAM_AGC_KI_RF__M;
3189 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3190 data &= ~SCU_RAM_AGC_KI_IF__M;
3191 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3192 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003193 status = write16(state, SCU_RAM_AGC_KI__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003194 if (status < 0)
3195 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003196 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003197 return status;
3198}
3199
Oliver Endrissebc7de22011-07-03 13:49:44 -03003200static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003201{
3202 int status;
3203
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003204 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003205 do {
3206 if (packetErr == NULL) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003207 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003208 if (status < 0)
3209 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003210 } else {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003211 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003212 if (status < 0)
3213 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003214 }
3215 } while (0);
3216 return status;
3217}
3218
3219static int DVBTScCommand(struct drxk_state *state,
3220 u16 cmd, u16 subcmd,
3221 u16 param0, u16 param1, u16 param2,
3222 u16 param3, u16 param4)
3223{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003224 u16 curCmd = 0;
3225 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003226 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003227 u16 scExec = 0;
3228 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003229
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003230 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003231 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003232 if (scExec != 1) {
3233 /* SC is not running */
3234 return -1;
3235 }
3236
3237 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003238 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003239 do {
3240 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003241 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003242 retryCnt++;
3243 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
3244 if (retryCnt >= DRXK_MAX_RETRIES)
3245 return -1;
3246 /* Write sub-command */
3247 switch (cmd) {
3248 /* All commands using sub-cmd */
3249 case OFDM_SC_RA_RAM_CMD_PROC_START:
3250 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3251 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003252 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003253 write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003254 break;
3255 default:
3256 /* Do nothing */
3257 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003258 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003259
3260 /* Write needed parameters and the command */
3261 switch (cmd) {
3262 /* All commands using 5 parameters */
3263 /* All commands using 4 parameters */
3264 /* All commands using 3 parameters */
3265 /* All commands using 2 parameters */
3266 case OFDM_SC_RA_RAM_CMD_PROC_START:
3267 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3268 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003269 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003270 write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003271 /* All commands using 1 parameters */
3272 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3273 case OFDM_SC_RA_RAM_CMD_USER_IO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003274 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003275 write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003276 /* All commands using 0 parameters */
3277 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3278 case OFDM_SC_RA_RAM_CMD_NULL:
3279 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003280 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003281 break;
3282 default:
3283 /* Unknown command */
3284 return -EINVAL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003285 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003286
3287 /* Wait until sc is ready processing command */
3288 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003289 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003290 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003291 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003292 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003293 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003294 if (retryCnt >= DRXK_MAX_RETRIES)
3295 return -1;
3296
3297 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003298 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003299 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003300 /* illegal command */
3301 return -EINVAL;
3302 }
3303
3304 /* Retreive results parameters from SC */
3305 switch (cmd) {
3306 /* All commands yielding 5 results */
3307 /* All commands yielding 4 results */
3308 /* All commands yielding 3 results */
3309 /* All commands yielding 2 results */
3310 /* All commands yielding 1 result */
3311 case OFDM_SC_RA_RAM_CMD_USER_IO:
3312 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003313 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003314 read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003315 /* All commands yielding 0 results */
3316 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3317 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3318 case OFDM_SC_RA_RAM_CMD_PROC_START:
3319 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3320 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3321 case OFDM_SC_RA_RAM_CMD_NULL:
3322 break;
3323 default:
3324 /* Unknown command */
3325 return -EINVAL;
3326 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003327 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003328 return status;
3329}
3330
Oliver Endrissebc7de22011-07-03 13:49:44 -03003331static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003332{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003333 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003334 int status;
3335
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003336 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003337 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003338 status = CtrlPowerMode(state, &powerMode);
3339 if (status < 0)
3340 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003341 } while (0);
3342 return status;
3343}
3344
Oliver Endrissebc7de22011-07-03 13:49:44 -03003345static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003346{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003347 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003348
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003349 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003350 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003351 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003352 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003353 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003354
3355 return status;
3356}
3357
3358#define DEFAULT_FR_THRES_8K 4000
3359static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3360{
3361
3362 int status;
3363
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003364 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003365 if (*enabled == true) {
3366 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003367 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003368 DEFAULT_FR_THRES_8K);
3369 } else {
3370 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003371 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003372 }
3373
3374 return status;
3375}
3376
3377static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3378 struct DRXKCfgDvbtEchoThres_t *echoThres)
3379{
3380 u16 data = 0;
3381 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003382
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003383 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003384 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003385 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003386 if (status < 0)
3387 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003388
Oliver Endrissebc7de22011-07-03 13:49:44 -03003389 switch (echoThres->fftMode) {
3390 case DRX_FFTMODE_2K:
3391 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3392 data |=
3393 ((echoThres->threshold <<
3394 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3395 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3396 break;
3397 case DRX_FFTMODE_8K:
3398 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3399 data |=
3400 ((echoThres->threshold <<
3401 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3402 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3403 break;
3404 default:
3405 return -1;
3406 break;
3407 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003408
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003409 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003410 if (status < 0)
3411 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003412 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003413
Oliver Endrissebc7de22011-07-03 13:49:44 -03003414 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003415}
3416
3417static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003418 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003419{
3420 int status;
3421
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003422 dprintk(1, "\n");
3423
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003424 switch (*speed) {
3425 case DRXK_DVBT_SQI_SPEED_FAST:
3426 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3427 case DRXK_DVBT_SQI_SPEED_SLOW:
3428 break;
3429 default:
3430 return -EINVAL;
3431 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003432 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003433 (u16) *speed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003434 return status;
3435}
3436
3437/*============================================================================*/
3438
3439/**
3440* \brief Activate DVBT specific presets
3441* \param demod instance of demodulator.
3442* \return DRXStatus_t.
3443*
3444* Called in DVBTSetStandard
3445*
3446*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003447static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003448{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003449 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003450
Oliver Endrissebc7de22011-07-03 13:49:44 -03003451 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3452 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003453
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003454 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003455 do {
3456 bool setincenable = false;
3457 bool setfrenable = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003458 status = DVBTCtrlSetIncEnable(state, &setincenable);
3459 if (status < 0)
3460 break;
3461 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3462 if (status < 0)
3463 break;
3464 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3465 if (status < 0)
3466 break;
3467 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3468 if (status < 0)
3469 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003470 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003471 if (status < 0)
3472 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003473 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003474
Oliver Endrissebc7de22011-07-03 13:49:44 -03003475 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003476}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003477
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003478/*============================================================================*/
3479
3480/**
3481* \brief Initialize channelswitch-independent settings for DVBT.
3482* \param demod instance of demodulator.
3483* \return DRXStatus_t.
3484*
3485* For ROM code channel filter taps are loaded from the bootloader. For microcode
3486* the DVB-T taps from the drxk_filters.h are used.
3487*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003488static int SetDVBTStandard(struct drxk_state *state,
3489 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003490{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003491 u16 cmdResult = 0;
3492 u16 data = 0;
3493 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003494
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003495 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003496
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003497 PowerUpDVBT(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003498 do {
3499 /* added antenna switch */
3500 SwitchAntennaToDVBT(state);
3501 /* send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003502 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
3503 if (status < 0)
3504 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003505
3506 /* send OFDM setenv command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003507 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3508 if (status < 0)
3509 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003510
3511 /* reset datapath for OFDM, processors first */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003512 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003513 if (status < 0)
3514 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003515 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003516 if (status < 0)
3517 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003518 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003519 if (status < 0)
3520 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003521
3522 /* IQM setup */
3523 /* synchronize on ofdstate->m_festart */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003524 status = write16(state, IQM_AF_UPD_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003525 if (status < 0)
3526 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003527 /* window size for clipping ADC detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003528 status = write16(state, IQM_AF_CLP_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003529 if (status < 0)
3530 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003531 /* window size for for sense pre-SAW detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003532 status = write16(state, IQM_AF_SNS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003533 if (status < 0)
3534 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003535 /* sense threshold for sense pre-SAW detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003536 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003537 if (status < 0)
3538 break;
3539 status = SetIqmAf(state, true);
3540 if (status < 0)
3541 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003542
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003543 status = write16(state, IQM_AF_AGC_RF__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003544 if (status < 0)
3545 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003546
3547 /* Impulse noise cruncher setup */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003548 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003549 if (status < 0)
3550 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003551 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003552 if (status < 0)
3553 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003554 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003555 if (status < 0)
3556 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003557
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003558 status = write16(state, IQM_RC_STRETCH__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003559 if (status < 0)
3560 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003561 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003562 if (status < 0)
3563 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003564 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003565 if (status < 0)
3566 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003567 status = write16(state, IQM_CF_SCALE__A, 1600);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003568 if (status < 0)
3569 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003570 status = write16(state, IQM_CF_SCALE_SH__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003571 if (status < 0)
3572 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003573
3574 /* virtual clipping threshold for clipping ADC detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003575 status = write16(state, IQM_AF_CLP_TH__A, 448);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003576 if (status < 0)
3577 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003578 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003579 if (status < 0)
3580 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003581
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003582 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3583 if (status < 0)
3584 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003585
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003586 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003587 if (status < 0)
3588 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003589 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003590 if (status < 0)
3591 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003592 /* enable power measurement interrupt */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003593 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003594 if (status < 0)
3595 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003596 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003597 if (status < 0)
3598 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003599
3600 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003601 status = ADCSynchronization(state);
3602 if (status < 0)
3603 break;
3604 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3605 if (status < 0)
3606 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003607
3608 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003609 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003610 if (status < 0)
3611 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003612
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003613 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3614 if (status < 0)
3615 break;
3616 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3617 if (status < 0)
3618 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003619
3620 /* Set Noise Estimation notch width and enable DC fix */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003621 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003622 if (status < 0)
3623 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003624 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003625 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003626 if (status < 0)
3627 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003628
3629 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003630 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003631 if (status < 0)
3632 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003633
Oliver Endrissebc7de22011-07-03 13:49:44 -03003634 if (!state->m_DRXK_A3_ROM_CODE) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003635 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003636 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003637 if (status < 0)
3638 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003639 }
3640
3641 /* OFDM_SC setup */
3642#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003643 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003644 if (status < 0)
3645 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003646 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003647 if (status < 0)
3648 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003649#endif
3650
3651 /* FEC setup */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003652 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003653 if (status < 0)
3654 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003655
3656
3657#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003658 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003659 if (status < 0)
3660 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003661#else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003662 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003663 if (status < 0)
3664 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003665#endif
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003666 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003667 if (status < 0)
3668 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003669
3670 /* Setup MPEG bus */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003671 status = MPEGTSDtoSetup(state, OM_DVBT);
3672 if (status < 0)
3673 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003674 /* Set DVBT Presets */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003675 status = DVBTActivatePresets(state);
3676 if (status < 0)
3677 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003678
3679 } while (0);
3680
Oliver Endrissebc7de22011-07-03 13:49:44 -03003681 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003682 printk(KERN_ERR "drxk: %s status - %08x\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003683
3684 return status;
3685}
3686
3687/*============================================================================*/
3688/**
3689* \brief Start dvbt demodulating for channel.
3690* \param demod instance of demodulator.
3691* \return DRXStatus_t.
3692*/
3693static int DVBTStart(struct drxk_state *state)
3694{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003695 u16 param1;
3696 int status;
3697 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003698
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003699 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003700 /* Start correct processes to get in lock */
3701 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
3702 do {
3703 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003704 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3705 if (status < 0)
3706 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003707 /* Start FEC OC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003708 status = MPEGTSStart(state);
3709 if (status < 0)
3710 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003711 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003712 if (status < 0)
3713 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003714 } while (0);
3715 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003716}
3717
3718
3719/*============================================================================*/
3720
3721/**
3722* \brief Set up dvbt demodulator for channel.
3723* \param demod instance of demodulator.
3724* \return DRXStatus_t.
3725* // original DVBTSetChannel()
3726*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003727static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3728 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003729{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003730 u16 cmdResult = 0;
3731 u16 transmissionParams = 0;
3732 u16 operationMode = 0;
3733 u32 iqmRcRateOfs = 0;
3734 u32 bandwidth = 0;
3735 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003736 int status;
3737
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003738 dprintk(1, "\n");
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003739 /* printk(KERN_DEBUG "drxk: %s IF =%d, TFO = %d\n", __func__, IntermediateFreqkHz, tunerFreqOffset); */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003740 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003741 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3742 if (status < 0)
3743 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003744
3745 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003746 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003747 if (status < 0)
3748 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003749
3750 /* Stop processors */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003751 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003752 if (status < 0)
3753 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003754 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003755 if (status < 0)
3756 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003757
3758 /* Mandatory fix, always stop CP, required to set spl offset back to
3759 hardware default (is set to 0 by ucode during pilot detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003760 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003761 if (status < 0)
3762 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003763
3764 /*== Write channel settings to device =====================================*/
3765
3766 /* mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003767 switch (state->param.u.ofdm.transmission_mode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003768 case TRANSMISSION_MODE_AUTO:
3769 default:
3770 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3771 /* fall through , try first guess DRX_FFTMODE_8K */
3772 case TRANSMISSION_MODE_8K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003773 transmissionParams |=
3774 OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003775 break;
3776 case TRANSMISSION_MODE_2K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003777 transmissionParams |=
3778 OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003779 break;
3780 }
3781
3782 /* guard */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003783 switch (state->param.u.ofdm.guard_interval) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003784 default:
3785 case GUARD_INTERVAL_AUTO:
3786 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3787 /* fall through , try first guess DRX_GUARD_1DIV4 */
3788 case GUARD_INTERVAL_1_4:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003789 transmissionParams |=
3790 OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003791 break;
3792 case GUARD_INTERVAL_1_32:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003793 transmissionParams |=
3794 OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003795 break;
3796 case GUARD_INTERVAL_1_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003797 transmissionParams |=
3798 OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003799 break;
3800 case GUARD_INTERVAL_1_8:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003801 transmissionParams |=
3802 OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003803 break;
3804 }
3805
3806 /* hierarchy */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003807 switch (state->param.u.ofdm.hierarchy_information) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003808 case HIERARCHY_AUTO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003809 case HIERARCHY_NONE:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003810 default:
3811 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3812 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003813 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3814 /* break; */
3815 case HIERARCHY_1:
3816 transmissionParams |=
3817 OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003818 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003819 case HIERARCHY_2:
3820 transmissionParams |=
3821 OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003822 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003823 case HIERARCHY_4:
3824 transmissionParams |=
3825 OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003826 break;
3827 }
3828
3829
3830 /* constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003831 switch (state->param.u.ofdm.constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003832 case QAM_AUTO:
3833 default:
3834 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3835 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3836 case QAM_64:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003837 transmissionParams |=
3838 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003839 break;
3840 case QPSK:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003841 transmissionParams |=
3842 OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003843 break;
3844 case QAM_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003845 transmissionParams |=
3846 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003847 break;
3848 }
3849#if 0
Oliver Endrissebc7de22011-07-03 13:49:44 -03003850 /* No hierachical channels support in BDA */
3851 /* Priority (only for hierarchical channels) */
3852 switch (channel->priority) {
3853 case DRX_PRIORITY_LOW:
3854 transmissionParams |=
3855 OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3856 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3857 OFDM_EC_SB_PRIOR_LO);
3858 break;
3859 case DRX_PRIORITY_HIGH:
3860 transmissionParams |=
3861 OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3862 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3863 OFDM_EC_SB_PRIOR_HI));
3864 break;
3865 case DRX_PRIORITY_UNKNOWN: /* fall through */
3866 default:
3867 return DRX_STS_INVALID_ARG;
3868 break;
3869 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003870#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03003871 /* Set Priorty high */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003872 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003873 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003874 if (status < 0)
3875 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003876#endif
3877
3878 /* coderate */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003879 switch (state->param.u.ofdm.code_rate_HP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003880 case FEC_AUTO:
3881 default:
3882 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3883 /* fall through , try first guess DRX_CODERATE_2DIV3 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003884 case FEC_2_3:
3885 transmissionParams |=
3886 OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003887 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003888 case FEC_1_2:
3889 transmissionParams |=
3890 OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003891 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003892 case FEC_3_4:
3893 transmissionParams |=
3894 OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003895 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003896 case FEC_5_6:
3897 transmissionParams |=
3898 OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003899 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003900 case FEC_7_8:
3901 transmissionParams |=
3902 OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003903 break;
3904 }
3905
3906 /* SAW filter selection: normaly not necesarry, but if wanted
3907 the application can select a SAW filter via the driver by using UIOs */
3908 /* First determine real bandwidth (Hz) */
3909 /* Also set delay for impulse noise cruncher */
3910 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3911 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3912 functions */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003913 switch (state->param.u.ofdm.bandwidth) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003914 case BANDWIDTH_AUTO:
3915 case BANDWIDTH_8_MHZ:
3916 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003917 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003918 if (status < 0)
3919 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003920 /* cochannel protection for PAL 8 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003921 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003922 if (status < 0)
3923 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003924 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003925 if (status < 0)
3926 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003927 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003928 if (status < 0)
3929 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003930 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003931 if (status < 0)
3932 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003933 break;
3934 case BANDWIDTH_7_MHZ:
3935 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003936 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003937 if (status < 0)
3938 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003939 /* cochannel protection for PAL 7 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003940 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003941 if (status < 0)
3942 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003943 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003944 if (status < 0)
3945 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003946 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003947 if (status < 0)
3948 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003949 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003950 if (status < 0)
3951 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003952 break;
3953 case BANDWIDTH_6_MHZ:
3954 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003955 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003956 if (status < 0)
3957 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003958 /* cochannel protection for NTSC 6 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003959 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003960 if (status < 0)
3961 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003962 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003963 if (status < 0)
3964 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003965 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003966 if (status < 0)
3967 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003968 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003969 if (status < 0)
3970 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003971 break;
Mauro Carvalho Chehabe16cede2011-07-03 18:18:14 -03003972 default:
3973 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003974 }
3975
Oliver Endrissebc7de22011-07-03 13:49:44 -03003976 if (iqmRcRateOfs == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003977 /* Now compute IQM_RC_RATE_OFS
3978 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3979 =>
3980 ((SysFreq / BandWidth) * (2^21)) - (2^23)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003981 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003982 /* (SysFreq / BandWidth) * (2^28) */
3983 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
3984 => assert(MAX(sysClk) < 16*MIN(bandwidth))
3985 => assert(109714272 > 48000000) = true so Frac 28 can be used */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003986 iqmRcRateOfs = Frac28a((u32)
3987 ((state->m_sysClockFreq *
3988 1000) / 3), bandwidth);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003989 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
3990 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003991 iqmRcRateOfs += 0x80L;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003992 iqmRcRateOfs = iqmRcRateOfs >> 7;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003993 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003994 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003995 }
3996
Oliver Endrissebc7de22011-07-03 13:49:44 -03003997 iqmRcRateOfs &=
3998 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
3999 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004000 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004001 if (status < 0)
4002 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004003
4004 /* Bandwidth setting done */
4005
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004006#if 0
4007 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4008 if (status < 0)
4009 break;
4010#endif
4011 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4012 if (status < 0)
4013 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004014
4015 /*== Start SC, write channel settings to SC ===============================*/
4016
4017 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004018 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004019 if (status < 0)
4020 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004021
4022 /* Enable SC after setting all other parameters */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004023 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004024 if (status < 0)
4025 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004026 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004027 if (status < 0)
4028 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004029
4030
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004031 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4032 if (status < 0)
4033 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004034
4035 /* Write SC parameter registers, set all AUTO flags in operation mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004036 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4037 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4038 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4039 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4040 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4041 status =
4042 DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4043 0, transmissionParams, param1, 0, 0, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004044 if (!state->m_DRXK_A3_ROM_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004045 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4046 if (status < 0)
4047 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004048
Oliver Endrissebc7de22011-07-03 13:49:44 -03004049 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004050
4051 return status;
4052}
4053
4054
4055/*============================================================================*/
4056
4057/**
4058* \brief Retreive lock status .
4059* \param demod Pointer to demodulator instance.
4060* \param lockStat Pointer to lock status structure.
4061* \return DRXStatus_t.
4062*
4063*/
4064static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4065{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004066 int status;
4067 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4068 OFDM_SC_RA_RAM_LOCK_FEC__M);
4069 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4070 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004071
Oliver Endrissebc7de22011-07-03 13:49:44 -03004072 u16 ScRaRamLock = 0;
4073 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004074
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004075 dprintk(1, "\n");
4076
Oliver Endrissebc7de22011-07-03 13:49:44 -03004077 /* driver 0.9.0 */
4078 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004079 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004080 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP) {
4081 /* SC not active; return DRX_NOT_LOCKED */
4082 *pLockStatus = NOT_LOCKED;
4083 return status;
4084 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004085
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004086 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004087
Oliver Endrissebc7de22011-07-03 13:49:44 -03004088 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4089 *pLockStatus = MPEG_LOCK;
4090 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4091 *pLockStatus = FEC_LOCK;
4092 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4093 *pLockStatus = DEMOD_LOCK;
4094 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4095 *pLockStatus = NEVER_LOCK;
4096 else
4097 *pLockStatus = NOT_LOCKED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004098
Oliver Endrissebc7de22011-07-03 13:49:44 -03004099 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004100}
4101
Oliver Endrissebc7de22011-07-03 13:49:44 -03004102static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004103{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004104 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
4105 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004106
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004107 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004108 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004109 status = CtrlPowerMode(state, &powerMode);
4110 if (status < 0)
4111 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004112
Oliver Endrissebc7de22011-07-03 13:49:44 -03004113 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004114
Oliver Endrissebc7de22011-07-03 13:49:44 -03004115 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004116}
4117
4118
Oliver Endrissebc7de22011-07-03 13:49:44 -03004119/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004120static int PowerDownQAM(struct drxk_state *state)
4121{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004122 u16 data = 0;
4123 u16 cmdResult;
4124 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004125
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004126 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004127 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004128 status = read16(state, SCU_COMM_EXEC__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004129 if (status < 0)
4130 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004131 if (data == SCU_COMM_EXEC_ACTIVE) {
4132 /*
4133 STOP demodulator
4134 QAM and HW blocks
4135 */
4136 /* stop all comstate->m_exec */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004137 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004138 if (status < 0)
4139 break;
4140 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
4141 if (status < 0)
4142 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004143 }
4144 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004145 status = SetIqmAf(state, false);
4146 if (status < 0)
4147 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004148 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004149
Oliver Endrissebc7de22011-07-03 13:49:44 -03004150 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004151}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004152
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004153/*============================================================================*/
4154
4155/**
4156* \brief Setup of the QAM Measurement intervals for signal quality
4157* \param demod instance of demod.
4158* \param constellation current constellation.
4159* \return DRXStatus_t.
4160*
4161* NOTE:
4162* Take into account that for certain settings the errorcounters can overflow.
4163* The implementation does not check this.
4164*
4165*/
4166static int SetQAMMeasurement(struct drxk_state *state,
4167 enum EDrxkConstellation constellation,
4168 u32 symbolRate)
4169{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004170 u32 fecBitsDesired = 0; /* BER accounting period */
4171 u32 fecRsPeriodTotal = 0; /* Total period */
4172 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4173 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004174 int status = 0;
4175
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004176 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004177
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004178 fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004179 do {
4180
4181 /* fecBitsDesired = symbolRate [kHz] *
4182 FrameLenght [ms] *
4183 (constellation + 1) *
4184 SyncLoss (== 1) *
4185 ViterbiLoss (==1)
Oliver Endrissebc7de22011-07-03 13:49:44 -03004186 */
4187 switch (constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004188 case DRX_CONSTELLATION_QAM16:
4189 fecBitsDesired = 4 * symbolRate;
4190 break;
4191 case DRX_CONSTELLATION_QAM32:
4192 fecBitsDesired = 5 * symbolRate;
4193 break;
4194 case DRX_CONSTELLATION_QAM64:
4195 fecBitsDesired = 6 * symbolRate;
4196 break;
4197 case DRX_CONSTELLATION_QAM128:
4198 fecBitsDesired = 7 * symbolRate;
4199 break;
4200 case DRX_CONSTELLATION_QAM256:
4201 fecBitsDesired = 8 * symbolRate;
4202 break;
4203 default:
4204 status = -EINVAL;
4205 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004206 status = status;
4207 if (status < 0)
4208 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004209
Oliver Endrissebc7de22011-07-03 13:49:44 -03004210 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4211 fecBitsDesired *= 500; /* meas. period [ms] */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004212
4213 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4214 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004215 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004216
4217 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4218 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4219 if (fecRsPrescale == 0) {
4220 /* Divide by zero (though impossible) */
4221 status = -1;
4222 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004223 status = status;
4224 if (status < 0)
4225 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004226 fecRsPeriod =
4227 ((u16) fecRsPeriodTotal +
4228 (fecRsPrescale >> 1)) / fecRsPrescale;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004229
4230 /* write corresponding registers */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004231 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004232 if (status < 0)
4233 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004234 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004235 if (status < 0)
4236 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004237 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004238 if (status < 0)
4239 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004240
4241 } while (0);
4242
Oliver Endrissebc7de22011-07-03 13:49:44 -03004243 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03004244 printk(KERN_ERR "drxk: %s: status - %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004245
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004246 return status;
4247}
4248
Oliver Endrissebc7de22011-07-03 13:49:44 -03004249static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004250{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004251 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004252
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004253 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004254 do {
4255 /* QAM Equalizer Setup */
4256 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004257 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004258 if (status < 0)
4259 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004260 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004261 if (status < 0)
4262 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004263 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004264 if (status < 0)
4265 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004266 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004267 if (status < 0)
4268 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004269 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004270 if (status < 0)
4271 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004272 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004273 if (status < 0)
4274 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004275 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004276 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004277 if (status < 0)
4278 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004279 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004280 if (status < 0)
4281 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004282 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004283 if (status < 0)
4284 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004285 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004286 if (status < 0)
4287 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004288 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004289 if (status < 0)
4290 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004291 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004292 if (status < 0)
4293 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004294
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004295 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004296 if (status < 0)
4297 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004298 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004299 if (status < 0)
4300 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004301 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004302 if (status < 0)
4303 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004304
Oliver Endrissebc7de22011-07-03 13:49:44 -03004305 /* QAM Slicer Settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004306 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004307 if (status < 0)
4308 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004309
Oliver Endrissebc7de22011-07-03 13:49:44 -03004310 /* QAM Loop Controller Coeficients */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004311 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004312 if (status < 0)
4313 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004314 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004315 if (status < 0)
4316 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004317 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004318 if (status < 0)
4319 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004320 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004321 if (status < 0)
4322 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004323 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004324 if (status < 0)
4325 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004326 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004327 if (status < 0)
4328 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004329 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004330 if (status < 0)
4331 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004332 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004333 if (status < 0)
4334 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004335
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004336 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004337 if (status < 0)
4338 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004339 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004340 if (status < 0)
4341 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004342 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004343 if (status < 0)
4344 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004345 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004346 if (status < 0)
4347 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004348 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004349 if (status < 0)
4350 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004351 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004352 if (status < 0)
4353 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004354 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004355 if (status < 0)
4356 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004357 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004358 if (status < 0)
4359 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004360 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004361 if (status < 0)
4362 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004363 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004364 if (status < 0)
4365 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004366 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004367 if (status < 0)
4368 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004369 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004370 if (status < 0)
4371 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004372
4373
Oliver Endrissebc7de22011-07-03 13:49:44 -03004374 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004375
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004376 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004377 if (status < 0)
4378 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004379 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004380 if (status < 0)
4381 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004382 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004383 if (status < 0)
4384 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004385 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004386 if (status < 0)
4387 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004388 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004389 if (status < 0)
4390 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004391 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004392 if (status < 0)
4393 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004394
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004395 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004396 if (status < 0)
4397 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004398 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004399 if (status < 0)
4400 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004401 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004402 if (status < 0)
4403 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004404
4405
Oliver Endrissebc7de22011-07-03 13:49:44 -03004406 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004407
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004408 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004409 if (status < 0)
4410 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004411 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004412 if (status < 0)
4413 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004414 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004415 if (status < 0)
4416 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004417 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004418 if (status < 0)
4419 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004420 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004421 if (status < 0)
4422 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004423 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004424 if (status < 0)
4425 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004426 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004427 if (status < 0)
4428 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004429 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004430
Oliver Endrissebc7de22011-07-03 13:49:44 -03004431 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004432}
4433
4434/*============================================================================*/
4435
4436/**
4437* \brief QAM32 specific setup
4438* \param demod instance of demod.
4439* \return DRXStatus_t.
4440*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004441static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004442{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004443 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004444
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004445 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004446 do {
4447 /* QAM Equalizer Setup */
4448 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004449 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004450 if (status < 0)
4451 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004452 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004453 if (status < 0)
4454 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004455 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004456 if (status < 0)
4457 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004458 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004459 if (status < 0)
4460 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004461 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004462 if (status < 0)
4463 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004464 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004465 if (status < 0)
4466 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004467
Oliver Endrissebc7de22011-07-03 13:49:44 -03004468 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004469 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004470 if (status < 0)
4471 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004472 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004473 if (status < 0)
4474 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004475 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004476 if (status < 0)
4477 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004478 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004479 if (status < 0)
4480 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004481 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004482 if (status < 0)
4483 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004484 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004485 if (status < 0)
4486 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004487
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004488 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004489 if (status < 0)
4490 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004491 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004492 if (status < 0)
4493 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004494 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004495 if (status < 0)
4496 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004497
Oliver Endrissebc7de22011-07-03 13:49:44 -03004498 /* QAM Slicer Settings */
4499
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004500 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004501 if (status < 0)
4502 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004503
4504
Oliver Endrissebc7de22011-07-03 13:49:44 -03004505 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004506
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004507 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004508 if (status < 0)
4509 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004510 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004511 if (status < 0)
4512 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004513 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004514 if (status < 0)
4515 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004516 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004517 if (status < 0)
4518 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004519 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004520 if (status < 0)
4521 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004522 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004523 if (status < 0)
4524 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004525 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004526 if (status < 0)
4527 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004528 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004529 if (status < 0)
4530 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004531
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004532 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004533 if (status < 0)
4534 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004535 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004536 if (status < 0)
4537 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004538 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004539 if (status < 0)
4540 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004541 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004542 if (status < 0)
4543 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004544 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004545 if (status < 0)
4546 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004547 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004548 if (status < 0)
4549 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004550 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004551 if (status < 0)
4552 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004553 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004554 if (status < 0)
4555 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004556 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004557 if (status < 0)
4558 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004559 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004560 if (status < 0)
4561 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004562 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004563 if (status < 0)
4564 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004565 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004566 if (status < 0)
4567 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004568
4569
Oliver Endrissebc7de22011-07-03 13:49:44 -03004570 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004571
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004572 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004573 if (status < 0)
4574 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004575 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004576 if (status < 0)
4577 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004578 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004579 if (status < 0)
4580 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004581 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004582 if (status < 0)
4583 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004584 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004585 if (status < 0)
4586 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004587 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004588 if (status < 0)
4589 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004590
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004591 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004592 if (status < 0)
4593 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004594 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004595 if (status < 0)
4596 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004597 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004598 if (status < 0)
4599 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004600
4601
Oliver Endrissebc7de22011-07-03 13:49:44 -03004602 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004603
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004604 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004605 if (status < 0)
4606 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004607 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004608 if (status < 0)
4609 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004610 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004611 if (status < 0)
4612 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004613 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004614 if (status < 0)
4615 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004616 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004617 if (status < 0)
4618 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004619 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004620 if (status < 0)
4621 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004622 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004623 if (status < 0)
4624 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004625 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004626
Oliver Endrissebc7de22011-07-03 13:49:44 -03004627 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004628}
4629
4630/*============================================================================*/
4631
4632/**
4633* \brief QAM64 specific setup
4634* \param demod instance of demod.
4635* \return DRXStatus_t.
4636*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004637static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004638{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004639 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004640
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004641 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004642 do {
4643 /* QAM Equalizer Setup */
4644 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004645 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004646 if (status < 0)
4647 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004648 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004649 if (status < 0)
4650 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004651 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004652 if (status < 0)
4653 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004654 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004655 if (status < 0)
4656 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004657 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004658 if (status < 0)
4659 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004660 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004661 if (status < 0)
4662 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004663
Oliver Endrissebc7de22011-07-03 13:49:44 -03004664 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004665 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004666 if (status < 0)
4667 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004668 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004669 if (status < 0)
4670 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004671 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004672 if (status < 0)
4673 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004674 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004675 if (status < 0)
4676 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004677 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004678 if (status < 0)
4679 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004680 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004681 if (status < 0)
4682 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004683
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004684 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004685 if (status < 0)
4686 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004687 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004688 if (status < 0)
4689 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004690 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004691 if (status < 0)
4692 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004693
4694 /* QAM Slicer Settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004695 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004696 if (status < 0)
4697 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004698
4699
Oliver Endrissebc7de22011-07-03 13:49:44 -03004700 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004701
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004702 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004703 if (status < 0)
4704 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004705 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004706 if (status < 0)
4707 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004708 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004709 if (status < 0)
4710 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004711 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004712 if (status < 0)
4713 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004714 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004715 if (status < 0)
4716 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004717 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004718 if (status < 0)
4719 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004720 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004721 if (status < 0)
4722 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004723 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004724 if (status < 0)
4725 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004726
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004727 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004728 if (status < 0)
4729 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004730 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004731 if (status < 0)
4732 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004733 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004734 if (status < 0)
4735 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004736 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004737 if (status < 0)
4738 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004739 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004740 if (status < 0)
4741 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004742 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004743 if (status < 0)
4744 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004745 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004746 if (status < 0)
4747 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004748 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004749 if (status < 0)
4750 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004751 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004752 if (status < 0)
4753 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004754 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004755 if (status < 0)
4756 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004757 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004758 if (status < 0)
4759 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004760 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004761 if (status < 0)
4762 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004763
4764
Oliver Endrissebc7de22011-07-03 13:49:44 -03004765 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004766
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004767 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004768 if (status < 0)
4769 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004770 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004771 if (status < 0)
4772 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004773 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004774 if (status < 0)
4775 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004776 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004777 if (status < 0)
4778 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004779 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004780 if (status < 0)
4781 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004782 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004783 if (status < 0)
4784 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004785
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004786 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004787 if (status < 0)
4788 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004789 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004790 if (status < 0)
4791 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004792 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004793 if (status < 0)
4794 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004795
4796
Oliver Endrissebc7de22011-07-03 13:49:44 -03004797 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004798
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004799 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004800 if (status < 0)
4801 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004802 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004803 if (status < 0)
4804 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004805 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004806 if (status < 0)
4807 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004808 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004809 if (status < 0)
4810 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004811 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004812 if (status < 0)
4813 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004814 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004815 if (status < 0)
4816 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004817 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004818 if (status < 0)
4819 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004820 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004821
Oliver Endrissebc7de22011-07-03 13:49:44 -03004822 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004823}
4824
4825/*============================================================================*/
4826
4827/**
4828* \brief QAM128 specific setup
4829* \param demod: instance of demod.
4830* \return DRXStatus_t.
4831*/
4832static int SetQAM128(struct drxk_state *state)
4833{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004834 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004835
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004836 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004837 do {
4838 /* QAM Equalizer Setup */
4839 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004840 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004841 if (status < 0)
4842 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004843 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004844 if (status < 0)
4845 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004846 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004847 if (status < 0)
4848 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004849 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004850 if (status < 0)
4851 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004852 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004853 if (status < 0)
4854 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004855 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004856 if (status < 0)
4857 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004858
Oliver Endrissebc7de22011-07-03 13:49:44 -03004859 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004860 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004861 if (status < 0)
4862 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004863 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004864 if (status < 0)
4865 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004866 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004867 if (status < 0)
4868 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004869 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004870 if (status < 0)
4871 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004872 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004873 if (status < 0)
4874 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004875 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004876 if (status < 0)
4877 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004878
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004879 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004880 if (status < 0)
4881 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004882 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004883 if (status < 0)
4884 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004885 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004886 if (status < 0)
4887 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004888
4889
Oliver Endrissebc7de22011-07-03 13:49:44 -03004890 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004891
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004892 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004893 if (status < 0)
4894 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004895
4896
Oliver Endrissebc7de22011-07-03 13:49:44 -03004897 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004898
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004899 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004900 if (status < 0)
4901 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004902 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004903 if (status < 0)
4904 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004905 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004906 if (status < 0)
4907 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004908 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004909 if (status < 0)
4910 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004911 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004912 if (status < 0)
4913 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004914 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004915 if (status < 0)
4916 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004917 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004918 if (status < 0)
4919 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004920 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004921 if (status < 0)
4922 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004923
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004924 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004925 if (status < 0)
4926 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004927 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004928 if (status < 0)
4929 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004930 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004931 if (status < 0)
4932 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004933 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004934 if (status < 0)
4935 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004936 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004937 if (status < 0)
4938 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004939 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004940 if (status < 0)
4941 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004942 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004943 if (status < 0)
4944 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004945 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004946 if (status < 0)
4947 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004948 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004949 if (status < 0)
4950 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004951 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004952 if (status < 0)
4953 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004954 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004955 if (status < 0)
4956 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004957 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004958 if (status < 0)
4959 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004960
4961
Oliver Endrissebc7de22011-07-03 13:49:44 -03004962 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004963
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004964 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004965 if (status < 0)
4966 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004967 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004968 if (status < 0)
4969 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004970 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004971 if (status < 0)
4972 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004973 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004974 if (status < 0)
4975 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004976 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004977 if (status < 0)
4978 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004979 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004980 if (status < 0)
4981 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004982
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004983 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004984 if (status < 0)
4985 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004986 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004987 if (status < 0)
4988 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004989
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004990 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004991 if (status < 0)
4992 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004993
Oliver Endrissebc7de22011-07-03 13:49:44 -03004994 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004995
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004996 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004997 if (status < 0)
4998 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004999 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005000 if (status < 0)
5001 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005002 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005003 if (status < 0)
5004 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005005 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005006 if (status < 0)
5007 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005008 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005009 if (status < 0)
5010 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005011 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005012 if (status < 0)
5013 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005014 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005015 if (status < 0)
5016 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005017 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005018
Oliver Endrissebc7de22011-07-03 13:49:44 -03005019 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005020}
5021
5022/*============================================================================*/
5023
5024/**
5025* \brief QAM256 specific setup
5026* \param demod: instance of demod.
5027* \return DRXStatus_t.
5028*/
5029static int SetQAM256(struct drxk_state *state)
5030{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005031 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005032
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005033 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005034 do {
5035 /* QAM Equalizer Setup */
5036 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005037 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005038 if (status < 0)
5039 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005040 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005041 if (status < 0)
5042 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005043 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005044 if (status < 0)
5045 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005046 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005047 if (status < 0)
5048 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005049 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005050 if (status < 0)
5051 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005052 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005053 if (status < 0)
5054 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005055
Oliver Endrissebc7de22011-07-03 13:49:44 -03005056 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005057 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005058 if (status < 0)
5059 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005060 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005061 if (status < 0)
5062 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005063 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005064 if (status < 0)
5065 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005066 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005067 if (status < 0)
5068 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005069 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005070 if (status < 0)
5071 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005072 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005073 if (status < 0)
5074 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005075
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005076 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005077 if (status < 0)
5078 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005079 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005080 if (status < 0)
5081 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005082 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005083 if (status < 0)
5084 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005085
Oliver Endrissebc7de22011-07-03 13:49:44 -03005086 /* QAM Slicer Settings */
5087
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005088 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005089 if (status < 0)
5090 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005091
5092
Oliver Endrissebc7de22011-07-03 13:49:44 -03005093 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005094
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005095 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005096 if (status < 0)
5097 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005098 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005099 if (status < 0)
5100 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005101 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005102 if (status < 0)
5103 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005104 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005105 if (status < 0)
5106 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005107 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005108 if (status < 0)
5109 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005110 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005111 if (status < 0)
5112 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005113 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005114 if (status < 0)
5115 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005116 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005117 if (status < 0)
5118 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005119
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005120 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005121 if (status < 0)
5122 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005123 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005124 if (status < 0)
5125 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005126 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005127 if (status < 0)
5128 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005129 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005130 if (status < 0)
5131 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005132 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005133 if (status < 0)
5134 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005135 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005136 if (status < 0)
5137 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005138 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005139 if (status < 0)
5140 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005141 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005142 if (status < 0)
5143 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005144 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005145 if (status < 0)
5146 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005147 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005148 if (status < 0)
5149 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005150 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005151 if (status < 0)
5152 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005153 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005154 if (status < 0)
5155 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005156
5157
Oliver Endrissebc7de22011-07-03 13:49:44 -03005158 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005159
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005160 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005161 if (status < 0)
5162 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005163 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005164 if (status < 0)
5165 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005166 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005167 if (status < 0)
5168 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005169 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005170 if (status < 0)
5171 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005172 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005173 if (status < 0)
5174 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005175 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005176 if (status < 0)
5177 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005178
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005179 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005180 if (status < 0)
5181 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005182 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005183 if (status < 0)
5184 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005185 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005186 if (status < 0)
5187 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005188
5189
Oliver Endrissebc7de22011-07-03 13:49:44 -03005190 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005191
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005192 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005193 if (status < 0)
5194 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005195 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005196 if (status < 0)
5197 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005198 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005199 if (status < 0)
5200 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005201 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005202 if (status < 0)
5203 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005204 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005205 if (status < 0)
5206 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005207 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005208 if (status < 0)
5209 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005210 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005211 if (status < 0)
5212 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005213 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005214
Oliver Endrissebc7de22011-07-03 13:49:44 -03005215 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005216}
5217
5218
5219/*============================================================================*/
5220/**
5221* \brief Reset QAM block.
5222* \param demod: instance of demod.
5223* \param channel: pointer to channel data.
5224* \return DRXStatus_t.
5225*/
5226static int QAMResetQAM(struct drxk_state *state)
5227{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005228 int status;
5229 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005230
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005231 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005232 do {
5233 /* Stop QAM comstate->m_exec */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005234 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005235 if (status < 0)
5236 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005237
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005238 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5239 if (status < 0)
5240 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005241 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005242
Oliver Endrissebc7de22011-07-03 13:49:44 -03005243 /* All done, all OK */
5244 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005245}
5246
5247/*============================================================================*/
5248
5249/**
5250* \brief Set QAM symbolrate.
5251* \param demod: instance of demod.
5252* \param channel: pointer to channel data.
5253* \return DRXStatus_t.
5254*/
5255static int QAMSetSymbolrate(struct drxk_state *state)
5256{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005257 u32 adcFrequency = 0;
5258 u32 symbFreq = 0;
5259 u32 iqmRcRate = 0;
5260 u16 ratesel = 0;
5261 u32 lcSymbRate = 0;
5262 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005263
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005264 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005265 do {
5266 /* Select & calculate correct IQM rate */
5267 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5268 ratesel = 0;
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005269 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005270 if (state->param.u.qam.symbol_rate <= 1188750)
5271 ratesel = 3;
5272 else if (state->param.u.qam.symbol_rate <= 2377500)
5273 ratesel = 2;
5274 else if (state->param.u.qam.symbol_rate <= 4755000)
5275 ratesel = 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005276 status = write16(state, IQM_FD_RATESEL__A, ratesel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005277 if (status < 0)
5278 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005279
Oliver Endrissebc7de22011-07-03 13:49:44 -03005280 /*
5281 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5282 */
5283 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5284 if (symbFreq == 0) {
5285 /* Divide by zero */
5286 return -1;
5287 }
5288 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5289 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5290 (1 << 23);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005291 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005292 if (status < 0)
5293 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005294 state->m_iqmRcRate = iqmRcRate;
5295 /*
5296 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5297 */
5298 symbFreq = state->param.u.qam.symbol_rate;
5299 if (adcFrequency == 0) {
5300 /* Divide by zero */
5301 return -1;
5302 }
5303 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5304 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5305 16);
5306 if (lcSymbRate > 511)
5307 lcSymbRate = 511;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005308 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005309 if (status < 0)
5310 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005311 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005312
Oliver Endrissebc7de22011-07-03 13:49:44 -03005313 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005314}
5315
5316/*============================================================================*/
5317
5318/**
5319* \brief Get QAM lock status.
5320* \param demod: instance of demod.
5321* \param channel: pointer to channel data.
5322* \return DRXStatus_t.
5323*/
5324
5325static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5326{
5327 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005328 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005329
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005330 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005331 status =
5332 scu_command(state,
5333 SCU_RAM_COMMAND_STANDARD_QAM |
5334 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5335 Result);
5336 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005337 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005338
5339 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005340 /* 0x0000 NOT LOCKED */
5341 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005342 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005343 /* 0x4000 DEMOD LOCKED */
5344 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005345 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005346 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5347 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005348 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005349 /* 0xC000 NEVER LOCKED */
5350 /* (system will never be able to lock to the signal) */
5351 /* TODO: check this, intermediate & standard specific lock states are not
5352 taken into account here */
5353 *pLockStatus = NEVER_LOCK;
5354 }
5355 return status;
5356}
5357
5358#define QAM_MIRROR__M 0x03
5359#define QAM_MIRROR_NORMAL 0x00
5360#define QAM_MIRRORED 0x01
5361#define QAM_MIRROR_AUTO_ON 0x02
5362#define QAM_LOCKRANGE__M 0x10
5363#define QAM_LOCKRANGE_NORMAL 0x10
5364
Oliver Endrissebc7de22011-07-03 13:49:44 -03005365static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5366 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005367{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005368 int status = 0;
5369 u8 parameterLen;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005370 u16 setEnvParameters[5];
5371 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5372 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005373
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005374 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005375 do {
5376 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005377 STEP 1: reset demodulator
5378 resets FEC DI and FEC RS
5379 resets QAM block
5380 resets SCU variables
5381 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005382 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005383 if (status < 0)
5384 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005385 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005386 if (status < 0)
5387 break;
5388 status = QAMResetQAM(state);
5389 if (status < 0)
5390 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005391
5392 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005393 STEP 2: configure demodulator
5394 -set env
5395 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5396 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005397 status = QAMSetSymbolrate(state);
5398 if (status < 0)
5399 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005400
5401 /* Env parameters */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005402 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005403 if (state->m_OperationMode == OM_QAM_ITU_C)
Oliver Endrissebc7de22011-07-03 13:49:44 -03005404 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005405 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005406 /* check for LOCKRANGE Extented */
5407 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005408 parameterLen = 4;
5409
5410 /* Set params */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005411 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005412 case QAM_256:
5413 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5414 break;
5415 case QAM_AUTO:
5416 case QAM_64:
5417 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5418 break;
5419 case QAM_16:
5420 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5421 break;
5422 case QAM_32:
5423 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5424 break;
5425 case QAM_128:
5426 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5427 break;
5428 default:
5429 status = -EINVAL;
5430 break;
5431 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005432 status = status;
5433 if (status < 0)
5434 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005435 setParamParameters[0] = state->m_Constellation; /* constellation */
5436 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005437
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005438 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5439 if (status < 0)
5440 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005441
5442
5443 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5444 setup constellation independent registers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005445#if 0
5446 status = SetFrequency (channel, tunerFreqOffset));
5447 if (status < 0)
5448 break;
5449#endif
5450 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5451 if (status < 0)
5452 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005453
5454 /* Setup BER measurement */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005455 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5456 if (status < 0)
5457 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005458
5459 /* Reset default values */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005460 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005461 if (status < 0)
5462 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005463 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005464 if (status < 0)
5465 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005466
Oliver Endrissebc7de22011-07-03 13:49:44 -03005467 /* Reset default LC values */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005468 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005469 if (status < 0)
5470 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005471 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005472 if (status < 0)
5473 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005474 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005475 if (status < 0)
5476 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005477 status = write16(state, QAM_LC_MODE__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005478 if (status < 0)
5479 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005480
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005481 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005482 if (status < 0)
5483 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005484 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005485 if (status < 0)
5486 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005487 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005488 if (status < 0)
5489 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005490 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005491 if (status < 0)
5492 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005493 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005494 if (status < 0)
5495 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005496 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005497 if (status < 0)
5498 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005499 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005500 if (status < 0)
5501 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005502 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005503 if (status < 0)
5504 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005505 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005506 if (status < 0)
5507 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005508 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005509 if (status < 0)
5510 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005511 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005512 if (status < 0)
5513 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005514 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005515 if (status < 0)
5516 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005517 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005518 if (status < 0)
5519 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005520 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005521 if (status < 0)
5522 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005523 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005524 if (status < 0)
5525 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005526
Oliver Endrissebc7de22011-07-03 13:49:44 -03005527 /* Mirroring, QAM-block starting point not inverted */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005528 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005529 if (status < 0)
5530 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005531
Oliver Endrissebc7de22011-07-03 13:49:44 -03005532 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005533 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005534 if (status < 0)
5535 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005536
Oliver Endrissebc7de22011-07-03 13:49:44 -03005537 /* STEP 4: constellation specific setup */
5538 switch (state->param.u.qam.modulation) {
5539 case QAM_16:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005540 status = SetQAM16(state);
5541 if (status < 0)
5542 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005543 break;
5544 case QAM_32:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005545 status = SetQAM32(state);
5546 if (status < 0)
5547 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005548 break;
5549 case QAM_AUTO:
5550 case QAM_64:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005551 status = SetQAM64(state);
5552 if (status < 0)
5553 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005554 break;
5555 case QAM_128:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005556 status = SetQAM128(state);
5557 if (status < 0)
5558 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005559 break;
5560 case QAM_256:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005561 status = SetQAM256(state);
5562 if (status < 0)
5563 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005564 break;
5565 default:
5566 return -1;
5567 break;
5568 } /* switch */
5569 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005570 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005571 if (status < 0)
5572 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005573
5574
Oliver Endrissebc7de22011-07-03 13:49:44 -03005575 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5576 /* extAttr->currentChannel.constellation = channel->constellation; */
5577 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005578 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5579 if (status < 0)
5580 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005581
Oliver Endrissebc7de22011-07-03 13:49:44 -03005582 /* Start processes */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005583 status = MPEGTSStart(state);
5584 if (status < 0)
5585 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005586 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005587 if (status < 0)
5588 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005589 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005590 if (status < 0)
5591 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005592 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005593 if (status < 0)
5594 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005595
Oliver Endrissebc7de22011-07-03 13:49:44 -03005596 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005597 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5598 if (status < 0)
5599 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005600
Oliver Endrissebc7de22011-07-03 13:49:44 -03005601 /* update global DRXK data container */
5602 /*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005603
Oliver Endrissebc7de22011-07-03 13:49:44 -03005604 /* All done, all OK */
5605 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005606
Oliver Endrissebc7de22011-07-03 13:49:44 -03005607 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005608 printk(KERN_ERR "drxk: %s %d\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005609
5610 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005611}
5612
Oliver Endrissebc7de22011-07-03 13:49:44 -03005613static int SetQAMStandard(struct drxk_state *state,
5614 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005615{
5616#ifdef DRXK_QAM_TAPS
5617#define DRXK_QAMA_TAPS_SELECT
5618#include "drxk_filters.h"
5619#undef DRXK_QAMA_TAPS_SELECT
5620#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03005621 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005622#endif
5623
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005624 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005625 do {
5626 /* added antenna switch */
5627 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005628
Oliver Endrissebc7de22011-07-03 13:49:44 -03005629 /* Ensure correct power-up mode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005630 status = PowerUpQAM(state);
5631 if (status < 0)
5632 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005633 /* Reset QAM block */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005634 status = QAMResetQAM(state);
5635 if (status < 0)
5636 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005637
Oliver Endrissebc7de22011-07-03 13:49:44 -03005638 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005639
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005640 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005641 if (status < 0)
5642 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005643 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005644 if (status < 0)
5645 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005646
Oliver Endrissebc7de22011-07-03 13:49:44 -03005647 /* Upload IQM Channel Filter settings by
5648 boot loader from ROM table */
5649 switch (oMode) {
5650 case OM_QAM_ITU_A:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005651 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5652 if (status < 0)
5653 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005654 break;
5655 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005656 status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5657 if (status < 0)
5658 break;
5659 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5660 if (status < 0)
5661 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005662 break;
5663 default:
5664 status = -EINVAL;
5665 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005666 status = status;
5667 if (status < 0)
5668 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005669
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005670 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005671 if (status < 0)
5672 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005673 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005674 if (status < 0)
5675 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005676 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005677 if (status < 0)
5678 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005679
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005680 status = write16(state, IQM_RC_STRETCH__A, 21);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005681 if (status < 0)
5682 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005683 status = write16(state, IQM_AF_CLP_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005684 if (status < 0)
5685 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005686 status = write16(state, IQM_AF_CLP_TH__A, 448);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005687 if (status < 0)
5688 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005689 status = write16(state, IQM_AF_SNS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005690 if (status < 0)
5691 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005692 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005693 if (status < 0)
5694 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005695
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005696 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005697 if (status < 0)
5698 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005699 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005700 if (status < 0)
5701 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005702 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005703 if (status < 0)
5704 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005705 status = write16(state, IQM_AF_UPD_SEL__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005706 if (status < 0)
5707 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005708
Oliver Endrissebc7de22011-07-03 13:49:44 -03005709 /* IQM Impulse Noise Processing Unit */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005710 status = write16(state, IQM_CF_CLP_VAL__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005711 if (status < 0)
5712 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005713 status = write16(state, IQM_CF_DATATH__A, 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005714 if (status < 0)
5715 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005716 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005717 if (status < 0)
5718 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005719 status = write16(state, IQM_CF_DET_LCT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005720 if (status < 0)
5721 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005722 status = write16(state, IQM_CF_WND_LEN__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005723 if (status < 0)
5724 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005725 status = write16(state, IQM_CF_PKDTH__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005726 if (status < 0)
5727 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005728 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005729 if (status < 0)
5730 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005731
Oliver Endrissebc7de22011-07-03 13:49:44 -03005732 /* turn on IQMAF. Must be done before setAgc**() */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005733 status = SetIqmAf(state, true);
5734 if (status < 0)
5735 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005736 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005737 if (status < 0)
5738 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005739
Oliver Endrissebc7de22011-07-03 13:49:44 -03005740 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005741 status = ADCSynchronization(state);
5742 if (status < 0)
5743 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005744
Oliver Endrissebc7de22011-07-03 13:49:44 -03005745 /* Set the FSM step period */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005746 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005747 if (status < 0)
5748 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005749
Oliver Endrissebc7de22011-07-03 13:49:44 -03005750 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005751 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005752 if (status < 0)
5753 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005754
Oliver Endrissebc7de22011-07-03 13:49:44 -03005755 /* No more resets of the IQM, current standard correctly set =>
5756 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005757
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005758 status = InitAGC(state, true);
5759 if (status < 0)
5760 break;
5761 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5762 if (status < 0)
5763 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005764
Oliver Endrissebc7de22011-07-03 13:49:44 -03005765 /* Configure AGC's */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005766 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5767 if (status < 0)
5768 break;
5769 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5770 if (status < 0)
5771 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005772
Oliver Endrissebc7de22011-07-03 13:49:44 -03005773 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005774 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005775 if (status < 0)
5776 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005777 } while (0);
5778 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005779}
5780
5781static int WriteGPIO(struct drxk_state *state)
5782{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005783 int status;
5784 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005785
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005786 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005787 do {
5788 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005789 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005790 if (status < 0)
5791 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005792
Oliver Endrissebc7de22011-07-03 13:49:44 -03005793 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005794 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005795 if (status < 0)
5796 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005797
Oliver Endrissebc7de22011-07-03 13:49:44 -03005798 if (state->m_hasSAWSW) {
5799 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005800 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005801 if (status < 0)
5802 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005803
Oliver Endrissebc7de22011-07-03 13:49:44 -03005804 /* use corresponding bit in io data output registar */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005805 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005806 if (status < 0)
5807 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005808 if (state->m_GPIO == 0)
5809 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5810 else
5811 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5812 /* write back to io data output register */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005813 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005814 if (status < 0)
5815 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005816
Oliver Endrissebc7de22011-07-03 13:49:44 -03005817 }
5818 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005819 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005820 if (status < 0)
5821 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005822 } while (0);
5823 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005824}
5825
5826static int SwitchAntennaToQAM(struct drxk_state *state)
5827{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005828 int status = -1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005829
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005830 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005831 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5832 if (state->m_GPIO != state->m_AntennaDVBC) {
5833 state->m_GPIO = state->m_AntennaDVBC;
5834 status = WriteGPIO(state);
5835 }
5836 }
5837 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005838}
5839
5840static int SwitchAntennaToDVBT(struct drxk_state *state)
5841{
5842 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005843
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005844 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005845 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5846 if (state->m_GPIO != state->m_AntennaDVBT) {
5847 state->m_GPIO = state->m_AntennaDVBT;
5848 status = WriteGPIO(state);
5849 }
5850 }
5851 return status;
5852}
5853
5854
5855static int PowerDownDevice(struct drxk_state *state)
5856{
5857 /* Power down to requested mode */
5858 /* Backup some register settings */
5859 /* Set pins with possible pull-ups connected to them in input mode */
5860 /* Analog power down */
5861 /* ADC power down */
5862 /* Power down device */
5863 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005864
5865 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005866 do {
5867 if (state->m_bPDownOpenBridge) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03005868 /* Open I2C bridge before power down of DRXK */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005869 status = ConfigureI2CBridge(state, true);
5870 if (status < 0)
5871 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005872 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005873 /* driver 0.9.0 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005874 status = DVBTEnableOFDMTokenRing(state, false);
5875 if (status < 0)
5876 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005877
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005878 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005879 if (status < 0)
5880 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005881 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005882 if (status < 0)
5883 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005884 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005885 status = HI_CfgCommand(state);
5886 if (status < 0)
5887 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005888 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005889
Oliver Endrissebc7de22011-07-03 13:49:44 -03005890 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005891 return -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005892
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005893 return 0;
5894}
5895
5896static int load_microcode(struct drxk_state *state, char *mc_name)
5897{
5898 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005899 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005900
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005901 dprintk(1, "\n");
5902
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005903 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5904 if (err < 0) {
5905 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005906 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005907 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005908 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005909 return err;
5910 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005911 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005912 release_firmware(fw);
5913 return err;
5914}
5915
5916static int init_drxk(struct drxk_state *state)
5917{
5918 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005919 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005920 u16 driverVersion;
5921
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005922 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005923 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
5924 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005925 status = PowerUpDevice(state);
5926 if (status < 0)
5927 break;
5928 status = DRXX_Open(state);
5929 if (status < 0)
5930 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005931 /* Soft reset of OFDM-, sys- and osc-clockdomain */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005932 status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005933 if (status < 0)
5934 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005935 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005936 if (status < 0)
5937 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005938 /* TODO is this needed, if yes how much delay in worst case scenario */
5939 msleep(1);
5940 state->m_DRXK_A3_PATCH_CODE = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005941 status = GetDeviceCapabilities(state);
5942 if (status < 0)
5943 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005944
5945 /* Bridge delay, uses oscilator clock */
5946 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5947 /* SDA brdige delay */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005948 state->m_HICfgBridgeDelay =
5949 (u16) ((state->m_oscClockFreq / 1000) *
5950 HI_I2C_BRIDGE_DELAY) / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005951 /* Clipping */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005952 if (state->m_HICfgBridgeDelay >
5953 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
5954 state->m_HICfgBridgeDelay =
5955 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005956 }
5957 /* SCL bridge delay, same as SDA for now */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005958 state->m_HICfgBridgeDelay +=
5959 state->m_HICfgBridgeDelay <<
5960 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005961
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005962 status = InitHI(state);
5963 if (status < 0)
5964 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005965 /* disable various processes */
5966#if NOA1ROM
Oliver Endrissebc7de22011-07-03 13:49:44 -03005967 if (!(state->m_DRXK_A1_ROM_CODE)
5968 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005969#endif
5970 {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005971 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005972 if (status < 0)
5973 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005974 }
5975
5976 /* disable MPEG port */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005977 status = MPEGTSDisable(state);
5978 if (status < 0)
5979 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005980
5981 /* Stop AUD and SCU */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005982 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005983 if (status < 0)
5984 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005985 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005986 if (status < 0)
5987 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005988
5989 /* enable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005990 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005991 if (status < 0)
5992 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005993
5994 /* include boot loader section */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005995 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005996 if (status < 0)
5997 break;
5998 status = BLChainCmd(state, 0, 6, 100);
5999 if (status < 0)
6000 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006001
6002#if 0
6003 if (state->m_DRXK_A3_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006004 status = DownloadMicrocode(state, DRXK_A3_microcode, DRXK_A3_microcode_length);
6005 if (status < 0)
6006 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006007#else
6008 load_microcode(state, "drxk_a3.mc");
6009#endif
6010#if NOA1ROM
6011 if (state->m_DRXK_A2_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006012 status = DownloadMicrocode(state, DRXK_A2_microcode, DRXK_A2_microcode_length);
6013 if (status < 0)
6014 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006015#endif
6016 /* disable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006017 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006018 if (status < 0)
6019 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006020
6021 /* Run SCU for a little while to initialize microcode version numbers */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006022 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006023 if (status < 0)
6024 break;
6025 status = DRXX_Open(state);
6026 if (status < 0)
6027 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006028 /* added for test */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006029 msleep(30);
6030
6031 powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006032 status = CtrlPowerMode(state, &powerMode);
6033 if (status < 0)
6034 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006035
6036 /* Stamp driver version number in SCU data RAM in BCD code
6037 Done to enable field application engineers to retreive drxdriver version
6038 via I2C from SCU RAM.
6039 Not using SCU command interface for SCU register access since no
6040 microcode may be present.
Oliver Endrissebc7de22011-07-03 13:49:44 -03006041 */
6042 driverVersion =
6043 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6044 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6045 ((DRXK_VERSION_MAJOR % 10) << 4) +
6046 (DRXK_VERSION_MINOR % 10);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006047 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006048 if (status < 0)
6049 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006050 driverVersion =
6051 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6052 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6053 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6054 (DRXK_VERSION_PATCH % 10);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006055 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006056 if (status < 0)
6057 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006058
Oliver Endrissebc7de22011-07-03 13:49:44 -03006059 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6060 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6061 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006062
6063 /* Dirty fix of default values for ROM/PATCH microcode
6064 Dirty because this fix makes it impossible to setup suitable values
6065 before calling DRX_Open. This solution requires changes to RF AGC speed
6066 to be done via the CTRL function after calling DRX_Open */
6067
Oliver Endrissebc7de22011-07-03 13:49:44 -03006068 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006069
6070 /* Reset driver debug flags to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006071 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006072 if (status < 0)
6073 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006074 /* driver 0.9.0 */
6075 /* Setup FEC OC:
6076 NOTE: No more full FEC resets allowed afterwards!! */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006077 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006078 if (status < 0)
6079 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006080 /* MPEGTS functions are still the same */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006081 status = MPEGTSDtoInit(state);
6082 if (status < 0)
6083 break;
6084 status = MPEGTSStop(state);
6085 if (status < 0)
6086 break;
6087 status = MPEGTSConfigurePolarity(state);
6088 if (status < 0)
6089 break;
6090 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6091 if (status < 0)
6092 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006093 /* added: configure GPIO */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006094 status = WriteGPIO(state);
6095 if (status < 0)
6096 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006097
Oliver Endrissebc7de22011-07-03 13:49:44 -03006098 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006099
6100 if (state->m_bPowerDown) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006101 status = PowerDownDevice(state);
6102 if (status < 0)
6103 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006104 state->m_DrxkState = DRXK_POWERED_DOWN;
6105 } else
6106 state->m_DrxkState = DRXK_STOPPED;
6107 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006108 }
6109
6110 return 0;
6111}
6112
Oliver Endrissebc7de22011-07-03 13:49:44 -03006113static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006114{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006115 struct drxk_state *state = fe->demodulator_priv;
6116
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006117 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006118 kfree(state);
6119}
6120
Oliver Endrissebc7de22011-07-03 13:49:44 -03006121static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006122{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006123 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006124
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006125 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006126 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006127 return -EBUSY;
6128 SetOperationMode(state, OM_QAM_ITU_A);
6129 return 0;
6130}
6131
Oliver Endrissebc7de22011-07-03 13:49:44 -03006132static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006133{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006134 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006135
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006136 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006137 ShutDown(state);
6138 mutex_unlock(&state->ctlock);
6139 return 0;
6140}
6141
Oliver Endrissebc7de22011-07-03 13:49:44 -03006142static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006143{
6144 struct drxk_state *state = fe->demodulator_priv;
6145
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006146 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006147 return ConfigureI2CBridge(state, enable ? true : false);
6148}
6149
Oliver Endrissebc7de22011-07-03 13:49:44 -03006150static int drxk_set_parameters(struct dvb_frontend *fe,
6151 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006152{
6153 struct drxk_state *state = fe->demodulator_priv;
6154 u32 IF;
6155
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006156 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006157 if (fe->ops.i2c_gate_ctrl)
6158 fe->ops.i2c_gate_ctrl(fe, 1);
6159 if (fe->ops.tuner_ops.set_params)
6160 fe->ops.tuner_ops.set_params(fe, p);
6161 if (fe->ops.i2c_gate_ctrl)
6162 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006163 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006164 fe->ops.tuner_ops.get_frequency(fe, &IF);
6165 Start(state, 0, IF);
6166
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006167 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006168
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006169 return 0;
6170}
6171
Oliver Endrissebc7de22011-07-03 13:49:44 -03006172static int drxk_c_get_frontend(struct dvb_frontend *fe,
6173 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006174{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006175 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006176 return 0;
6177}
6178
6179static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6180{
6181 struct drxk_state *state = fe->demodulator_priv;
6182 u32 stat;
6183
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006184 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006185 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006186 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006187 if (stat == MPEG_LOCK)
6188 *status |= 0x1f;
6189 if (stat == FEC_LOCK)
6190 *status |= 0x0f;
6191 if (stat == DEMOD_LOCK)
6192 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006193 return 0;
6194}
6195
6196static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6197{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006198 dprintk(1, "\n");
6199
Oliver Endrissebc7de22011-07-03 13:49:44 -03006200 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006201 return 0;
6202}
6203
Oliver Endrissebc7de22011-07-03 13:49:44 -03006204static int drxk_read_signal_strength(struct dvb_frontend *fe,
6205 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006206{
6207 struct drxk_state *state = fe->demodulator_priv;
6208 u32 val;
6209
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006210 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006211 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006212 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006213 return 0;
6214}
6215
6216static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6217{
6218 struct drxk_state *state = fe->demodulator_priv;
6219 s32 snr2;
6220
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006221 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006222 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006223 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006224 return 0;
6225}
6226
6227static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6228{
6229 struct drxk_state *state = fe->demodulator_priv;
6230 u16 err;
6231
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006232 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006233 DVBTQAMGetAccPktErr(state, &err);
6234 *ucblocks = (u32) err;
6235 return 0;
6236}
6237
Oliver Endrissebc7de22011-07-03 13:49:44 -03006238static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6239 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006240{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006241 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006242 sets->min_delay_ms = 3000;
6243 sets->max_drift = 0;
6244 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006245 return 0;
6246}
6247
Oliver Endrissebc7de22011-07-03 13:49:44 -03006248static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006249{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006250#if 0
6251 struct drxk_state *state = fe->demodulator_priv;
6252
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006253 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006254 kfree(state);
6255#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006256}
6257
Oliver Endrissebc7de22011-07-03 13:49:44 -03006258static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006259{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006260 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006261
6262 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006263 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006264 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006265 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006266 return 0;
6267}
6268
Oliver Endrissebc7de22011-07-03 13:49:44 -03006269static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006270{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006271 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006272
6273 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006274 mutex_unlock(&state->ctlock);
6275 return 0;
6276}
6277
Oliver Endrissebc7de22011-07-03 13:49:44 -03006278static int drxk_t_get_frontend(struct dvb_frontend *fe,
6279 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006280{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006281 dprintk(1, "\n");
6282
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006283 return 0;
6284}
6285
6286static struct dvb_frontend_ops drxk_c_ops = {
6287 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006288 .name = "DRXK DVB-C",
6289 .type = FE_QAM,
6290 .frequency_stepsize = 62500,
6291 .frequency_min = 47000000,
6292 .frequency_max = 862000000,
6293 .symbol_rate_min = 870000,
6294 .symbol_rate_max = 11700000,
6295 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6296 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006297 .release = drxk_c_release,
6298 .init = drxk_c_init,
6299 .sleep = drxk_c_sleep,
6300 .i2c_gate_ctrl = drxk_gate_ctrl,
6301
6302 .set_frontend = drxk_set_parameters,
6303 .get_frontend = drxk_c_get_frontend,
6304 .get_tune_settings = drxk_c_get_tune_settings,
6305
6306 .read_status = drxk_read_status,
6307 .read_ber = drxk_read_ber,
6308 .read_signal_strength = drxk_read_signal_strength,
6309 .read_snr = drxk_read_snr,
6310 .read_ucblocks = drxk_read_ucblocks,
6311};
6312
6313static struct dvb_frontend_ops drxk_t_ops = {
6314 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006315 .name = "DRXK DVB-T",
6316 .type = FE_OFDM,
6317 .frequency_min = 47125000,
6318 .frequency_max = 865000000,
6319 .frequency_stepsize = 166667,
6320 .frequency_tolerance = 0,
6321 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6322 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6323 FE_CAN_FEC_AUTO |
6324 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6325 FE_CAN_QAM_AUTO |
6326 FE_CAN_TRANSMISSION_MODE_AUTO |
6327 FE_CAN_GUARD_INTERVAL_AUTO |
6328 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006329 .release = drxk_t_release,
6330 .init = drxk_t_init,
6331 .sleep = drxk_t_sleep,
6332 .i2c_gate_ctrl = drxk_gate_ctrl,
6333
6334 .set_frontend = drxk_set_parameters,
6335 .get_frontend = drxk_t_get_frontend,
6336
6337 .read_status = drxk_read_status,
6338 .read_ber = drxk_read_ber,
6339 .read_signal_strength = drxk_read_signal_strength,
6340 .read_snr = drxk_read_snr,
6341 .read_ucblocks = drxk_read_ucblocks,
6342};
6343
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006344struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6345 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006346 struct dvb_frontend **fe_t)
6347{
6348 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006349 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006350
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006351 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006352 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006353 if (!state)
6354 return NULL;
6355
Oliver Endrissebc7de22011-07-03 13:49:44 -03006356 state->i2c = i2c;
6357 state->demod_address = adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006358
6359 mutex_init(&state->mutex);
6360 mutex_init(&state->ctlock);
6361
Oliver Endrissebc7de22011-07-03 13:49:44 -03006362 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6363 sizeof(struct dvb_frontend_ops));
6364 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6365 sizeof(struct dvb_frontend_ops));
6366 state->c_frontend.demodulator_priv = state;
6367 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006368
6369 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006370 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006371 goto error;
6372 *fe_t = &state->t_frontend;
6373 return &state->c_frontend;
6374
6375error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006376 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006377 kfree(state);
6378 return NULL;
6379}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006380EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006381
6382MODULE_DESCRIPTION("DRX-K driver");
6383MODULE_AUTHOR("Ralph Metzler");
6384MODULE_LICENSE("GPL");