blob: 1452e8228a6fb9debd9d77e9817d168c1e6b76fe [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;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300378
379 if (state->single_master)
380 flags |= 0xC0;
381
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300382 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
383 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
384 mm1[1] = ((reg >> 16) & 0xFF);
385 mm1[2] = ((reg >> 24) & 0xFF) | flags;
386 mm1[3] = ((reg >> 7) & 0xFF);
387 len = 4;
388 } else {
389 mm1[0] = ((reg << 1) & 0xFF);
390 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
391 len = 2;
392 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300393 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300394 if (i2c_read(state->i2c, adr, mm1, len, mm2, 2) < 0)
395 return -1;
396 if (data)
397 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300398
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300399 return 0;
400}
401
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300402static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300403{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300404 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300405}
406
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300407static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300408{
409 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300410
411 if (state->single_master)
412 flags |= 0xC0;
413
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300414 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
415 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
416 mm1[1] = ((reg >> 16) & 0xFF);
417 mm1[2] = ((reg >> 24) & 0xFF) | flags;
418 mm1[3] = ((reg >> 7) & 0xFF);
419 len = 4;
420 } else {
421 mm1[0] = ((reg << 1) & 0xFF);
422 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
423 len = 2;
424 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300425 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300426 if (i2c_read(state->i2c, adr, mm1, len, mm2, 4) < 0)
427 return -1;
428 if (data)
429 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300430 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300431
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300432 return 0;
433}
434
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300435static int read32(struct drxk_state *state, u32 reg, u32 *data)
436{
437 return read32_flags(state, reg, data, 0);
438}
439
440static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300441{
442 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300443
444 if (state->single_master)
445 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300446 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
447 mm[0] = (((reg << 1) & 0xFF) | 0x01);
448 mm[1] = ((reg >> 16) & 0xFF);
449 mm[2] = ((reg >> 24) & 0xFF) | flags;
450 mm[3] = ((reg >> 7) & 0xFF);
451 len = 4;
452 } else {
453 mm[0] = ((reg << 1) & 0xFF);
454 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
455 len = 2;
456 }
457 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300458 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300459
460 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300461 if (i2c_write(state->i2c, adr, mm, len + 2) < 0)
462 return -1;
463 return 0;
464}
465
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300466static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300467{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300468 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300469}
470
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300471static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300472{
473 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300474
475 if (state->single_master)
476 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300477 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
478 mm[0] = (((reg << 1) & 0xFF) | 0x01);
479 mm[1] = ((reg >> 16) & 0xFF);
480 mm[2] = ((reg >> 24) & 0xFF) | flags;
481 mm[3] = ((reg >> 7) & 0xFF);
482 len = 4;
483 } else {
484 mm[0] = ((reg << 1) & 0xFF);
485 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
486 len = 2;
487 }
488 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300489 mm[len + 1] = (data >> 8) & 0xff;
490 mm[len + 2] = (data >> 16) & 0xff;
491 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300492 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300493 if (i2c_write(state->i2c, adr, mm, len + 4) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300494 return -1;
495 return 0;
496}
497
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300498static int write32(struct drxk_state *state, u32 reg, u32 data)
499{
500 return write32_flags(state, reg, data, 0);
501}
502
503static int write_block(struct drxk_state *state, u32 Address,
504 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300505{
506 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300507 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300508
509 if (state->single_master)
510 Flags |= 0xC0;
511
Oliver Endrissebc7de22011-07-03 13:49:44 -0300512 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300513 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300514 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300515 u8 *AdrBuf = &state->Chunk[0];
516 u32 AdrLength = 0;
517
Oliver Endrissebc7de22011-07-03 13:49:44 -0300518 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
519 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
520 AdrBuf[1] = ((Address >> 16) & 0xFF);
521 AdrBuf[2] = ((Address >> 24) & 0xFF);
522 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300523 AdrBuf[2] |= Flags;
524 AdrLength = 4;
525 if (Chunk == state->m_ChunkSize)
526 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300527 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300528 AdrBuf[0] = ((Address << 1) & 0xFF);
529 AdrBuf[1] = (((Address >> 16) & 0x0F) |
530 ((Address >> 18) & 0xF0));
531 AdrLength = 2;
532 }
533 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300534 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
535 if (debug > 1) {
536 int i;
537 if (pBlock)
538 for (i = 0; i < Chunk; i++)
539 printk(KERN_CONT " %02x", pBlock[i]);
540 printk(KERN_CONT "\n");
541 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300542 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300543 &state->Chunk[0], Chunk + AdrLength);
544 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300545 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
546 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300547 break;
548 }
549 pBlock += Chunk;
550 Address += (Chunk >> 1);
551 BlkSize -= Chunk;
552 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300553 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300554}
555
556#ifndef DRXK_MAX_RETRIES_POWERUP
557#define DRXK_MAX_RETRIES_POWERUP 20
558#endif
559
560int PowerUpDevice(struct drxk_state *state)
561{
562 int status;
563 u8 data = 0;
564 u16 retryCount = 0;
565
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300566 dprintk(1, "\n");
567
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300568 status = i2c_read1(state->i2c, state->demod_address, &data);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300569 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300570 do {
571 data = 0;
572 if (i2c_write(state->i2c,
573 state->demod_address, &data, 1) < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300574 printk(KERN_ERR "drxk: powerup failed\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300575 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300576 retryCount++;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300577 } while (i2c_read1(state->i2c,
578 state->demod_address, &data) < 0 &&
579 (retryCount < DRXK_MAX_RETRIES_POWERUP));
580 if (retryCount >= DRXK_MAX_RETRIES_POWERUP)
581 return -1;
582 do {
583 /* Make sure all clk domains are active */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300584 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300585 if (status < 0)
586 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300587 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300588 if (status < 0)
589 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300590 /* Enable pll lock tests */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300591 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300592 if (status < 0)
593 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300594 state->m_currentPowerMode = DRX_POWER_UP;
595 } while (0);
596 return status;
597}
598
599
600static int init_state(struct drxk_state *state)
601{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300602 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
603 u32 ulVSBIfAgcOutputLevel = 0;
604 u32 ulVSBIfAgcMinLevel = 0;
605 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
606 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300607
Oliver Endrissebc7de22011-07-03 13:49:44 -0300608 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
609 u32 ulVSBRfAgcOutputLevel = 0;
610 u32 ulVSBRfAgcMinLevel = 0;
611 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
612 u32 ulVSBRfAgcSpeed = 3;
613 u32 ulVSBRfAgcTop = 9500;
614 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300615
Oliver Endrissebc7de22011-07-03 13:49:44 -0300616 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
617 u32 ulATVIfAgcOutputLevel = 0;
618 u32 ulATVIfAgcMinLevel = 0;
619 u32 ulATVIfAgcMaxLevel = 0;
620 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300621
Oliver Endrissebc7de22011-07-03 13:49:44 -0300622 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
623 u32 ulATVRfAgcOutputLevel = 0;
624 u32 ulATVRfAgcMinLevel = 0;
625 u32 ulATVRfAgcMaxLevel = 0;
626 u32 ulATVRfAgcTop = 9500;
627 u32 ulATVRfAgcCutOffCurrent = 4000;
628 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300629
630 u32 ulQual83 = DEFAULT_MER_83;
631 u32 ulQual93 = DEFAULT_MER_93;
632
633 u32 ulDVBTStaticTSClock = 1;
634 u32 ulDVBCStaticTSClock = 1;
635
636 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
637 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
638
639 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
640 /* io_pad_cfg_mode output mode is drive always */
641 /* io_pad_cfg_drive is set to power 2 (23 mA) */
642 u32 ulGPIOCfg = 0x0113;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300643 u32 ulGPIO = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300644 u32 ulSerialMode = 1;
645 u32 ulInvertTSClock = 0;
646 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
647 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
648 u32 ulDVBTBitrate = 50000000;
649 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
650
651 u32 ulInsertRSByte = 0;
652
653 u32 ulRfMirror = 1;
654 u32 ulPowerDown = 0;
655
656 u32 ulAntennaDVBT = 1;
657 u32 ulAntennaDVBC = 0;
658 u32 ulAntennaSwitchDVBTDVBC = 0;
659
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300660 dprintk(1, "\n");
661
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300662 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300663 state->m_hasDVBT = false;
664 state->m_hasDVBC = false;
665 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300666 state->m_hasOOB = false;
667 state->m_hasAudio = false;
668
669 state->m_ChunkSize = 124;
670
671 state->m_oscClockFreq = 0;
672 state->m_smartAntInverted = false;
673 state->m_bPDownOpenBridge = false;
674
675 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300676 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300677 /* Timing div, 250ns/Psys */
678 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
679 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
680 HI_I2C_DELAY) / 1000;
681 /* Clipping */
682 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
683 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
684 state->m_HICfgWakeUpKey = (state->demod_address << 1);
685 /* port/bridge/power down ctrl */
686 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
687
688 state->m_bPowerDown = (ulPowerDown != 0);
689
690 state->m_DRXK_A1_PATCH_CODE = false;
691 state->m_DRXK_A1_ROM_CODE = false;
692 state->m_DRXK_A2_ROM_CODE = false;
693 state->m_DRXK_A3_ROM_CODE = false;
694 state->m_DRXK_A2_PATCH_CODE = false;
695 state->m_DRXK_A3_PATCH_CODE = false;
696
697 /* Init AGC and PGA parameters */
698 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300699 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
700 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
701 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
702 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
703 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300704 state->m_vsbPgaCfg = 140;
705
706 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300707 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
708 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
709 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
710 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
711 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
712 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
713 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
714 state->m_vsbPreSawCfg.reference = 0x07;
715 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300716
717 state->m_Quality83percent = DEFAULT_MER_83;
718 state->m_Quality93percent = DEFAULT_MER_93;
719 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
720 state->m_Quality83percent = ulQual83;
721 state->m_Quality93percent = ulQual93;
722 }
723
724 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300725 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
726 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
727 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
728 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
729 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300730
731 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300732 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
733 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
734 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
735 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
736 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
737 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
738 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
739 state->m_atvPreSawCfg.reference = 0x04;
740 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300741
742
743 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300744 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
745 state->m_dvbtRfAgcCfg.outputLevel = 0;
746 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
747 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
748 state->m_dvbtRfAgcCfg.top = 0x2100;
749 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
750 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300751
752
753 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300754 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
755 state->m_dvbtIfAgcCfg.outputLevel = 0;
756 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
757 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
758 state->m_dvbtIfAgcCfg.top = 13424;
759 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
760 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300761 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300762 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
763 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300764
Oliver Endrissebc7de22011-07-03 13:49:44 -0300765 state->m_dvbtPreSawCfg.reference = 4;
766 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300767
768 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300769 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
770 state->m_qamRfAgcCfg.outputLevel = 0;
771 state->m_qamRfAgcCfg.minOutputLevel = 6023;
772 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
773 state->m_qamRfAgcCfg.top = 0x2380;
774 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
775 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300776
777 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300778 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
779 state->m_qamIfAgcCfg.outputLevel = 0;
780 state->m_qamIfAgcCfg.minOutputLevel = 0;
781 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
782 state->m_qamIfAgcCfg.top = 0x0511;
783 state->m_qamIfAgcCfg.cutOffCurrent = 0;
784 state->m_qamIfAgcCfg.speed = 3;
785 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300786 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
787
Oliver Endrissebc7de22011-07-03 13:49:44 -0300788 state->m_qamPgaCfg = 140;
789 state->m_qamPreSawCfg.reference = 4;
790 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300791
792 state->m_OperationMode = OM_NONE;
793 state->m_DrxkState = DRXK_UNINITIALIZED;
794
795 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300796 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
797 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
798 state->m_enableParallel = true; /* If TRUE;
799 parallel out otherwise serial */
800 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
801 state->m_invertERR = false; /* If TRUE; invert ERR signal */
802 state->m_invertSTR = false; /* If TRUE; invert STR signals */
803 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
804 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300805 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300806 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300807 /* If TRUE; static MPEG clockrate will be used;
808 otherwise clockrate will adapt to the bitrate of the TS */
809
810 state->m_DVBTBitrate = ulDVBTBitrate;
811 state->m_DVBCBitrate = ulDVBCBitrate;
812
813 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
814 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
815
816 /* Maximum bitrate in b/s in case static clockrate is selected */
817 state->m_mpegTsStaticBitrate = 19392658;
818 state->m_disableTEIhandling = false;
819
820 if (ulInsertRSByte)
821 state->m_insertRSByte = true;
822
823 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
824 if (ulMpegLockTimeOut < 10000)
825 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
826 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
827 if (ulDemodLockTimeOut < 10000)
828 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
829
Oliver Endrissebc7de22011-07-03 13:49:44 -0300830 /* QAM defaults */
831 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300832 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300833 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
834 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300835
836 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
837 state->m_agcFastClipCtrlDelay = 0;
838
839 state->m_GPIOCfg = (ulGPIOCfg);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300840 state->m_GPIO = (ulGPIO == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300841
842 state->m_AntennaDVBT = (ulAntennaDVBT == 0 ? 0 : 1);
843 state->m_AntennaDVBC = (ulAntennaDVBC == 0 ? 0 : 1);
844 state->m_AntennaSwitchDVBTDVBC =
Oliver Endrissebc7de22011-07-03 13:49:44 -0300845 (ulAntennaSwitchDVBTDVBC == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300846
847 state->m_bPowerDown = false;
848 state->m_currentPowerMode = DRX_POWER_DOWN;
849
850 state->m_enableParallel = (ulSerialMode == 0);
851
852 state->m_rfmirror = (ulRfMirror == 0);
853 state->m_IfAgcPol = false;
854 return 0;
855}
856
857static int DRXX_Open(struct drxk_state *state)
858{
859 int status = 0;
860 u32 jtag = 0;
861 u16 bid = 0;
862 u16 key = 0;
863
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300864 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300865 do {
866 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300867 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300868 if (status < 0)
869 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300870 /* Check device id */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300871 status = read16(state, SIO_TOP_COMM_KEY__A, &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 = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300875 if (status < 0)
876 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300877 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300878 if (status < 0)
879 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300880 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300881 if (status < 0)
882 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300883 status = write16(state, SIO_TOP_COMM_KEY__A, key);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300884 if (status < 0)
885 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300886 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300887 return status;
888}
889
890static int GetDeviceCapabilities(struct drxk_state *state)
891{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300892 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300893 u32 sioTopJtagidLo = 0;
894 int status;
895
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300896 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300897 do {
898 /* driver 0.9.0 */
899 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300900 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300901 if (status < 0)
902 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300903
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300904 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300905 if (status < 0)
906 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300907 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300908 if (status < 0)
909 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300910 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300911 if (status < 0)
912 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300913
914 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
915 case 0:
916 /* ignore (bypass ?) */
917 break;
918 case 1:
919 /* 27 MHz */
920 state->m_oscClockFreq = 27000;
921 break;
922 case 2:
923 /* 20.25 MHz */
924 state->m_oscClockFreq = 20250;
925 break;
926 case 3:
927 /* 4 MHz */
928 state->m_oscClockFreq = 20250;
929 break;
930 default:
931 return -1;
932 }
933 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300934 Determine device capabilities
935 Based on pinning v14
936 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300937 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300938 if (status < 0)
939 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300940 /* driver 0.9.0 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300941 switch ((sioTopJtagidLo >> 29) & 0xF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300942 case 0:
943 state->m_deviceSpin = DRXK_SPIN_A1;
944 break;
945 case 2:
946 state->m_deviceSpin = DRXK_SPIN_A2;
947 break;
948 case 3:
949 state->m_deviceSpin = DRXK_SPIN_A3;
950 break;
951 default:
952 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
953 status = -1;
954 break;
955 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300956 switch ((sioTopJtagidLo >> 12) & 0xFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300957 case 0x13:
958 /* typeId = DRX3913K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300959 state->m_hasLNA = false;
960 state->m_hasOOB = false;
961 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300962 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300963 state->m_hasDVBT = true;
964 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300965 state->m_hasSAWSW = true;
966 state->m_hasGPIO2 = false;
967 state->m_hasGPIO1 = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300968 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300969 break;
970 case 0x15:
971 /* typeId = DRX3915K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300972 state->m_hasLNA = false;
973 state->m_hasOOB = false;
974 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300975 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300976 state->m_hasDVBT = true;
977 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300978 state->m_hasSAWSW = true;
979 state->m_hasGPIO2 = true;
980 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300981 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300982 break;
983 case 0x16:
984 /* typeId = DRX3916K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300985 state->m_hasLNA = false;
986 state->m_hasOOB = false;
987 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300988 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300989 state->m_hasDVBT = true;
990 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300991 state->m_hasSAWSW = true;
992 state->m_hasGPIO2 = true;
993 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300994 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300995 break;
996 case 0x18:
997 /* typeId = DRX3918K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300998 state->m_hasLNA = false;
999 state->m_hasOOB = false;
1000 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001001 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001002 state->m_hasDVBT = true;
1003 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001004 state->m_hasSAWSW = true;
1005 state->m_hasGPIO2 = true;
1006 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001007 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001008 break;
1009 case 0x21:
1010 /* typeId = DRX3921K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001011 state->m_hasLNA = false;
1012 state->m_hasOOB = false;
1013 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001014 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001015 state->m_hasDVBT = true;
1016 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001017 state->m_hasSAWSW = true;
1018 state->m_hasGPIO2 = true;
1019 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001020 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001021 break;
1022 case 0x23:
1023 /* typeId = DRX3923K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001024 state->m_hasLNA = false;
1025 state->m_hasOOB = false;
1026 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001027 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001028 state->m_hasDVBT = true;
1029 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001030 state->m_hasSAWSW = true;
1031 state->m_hasGPIO2 = true;
1032 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001033 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001034 break;
1035 case 0x25:
1036 /* typeId = DRX3925K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001037 state->m_hasLNA = false;
1038 state->m_hasOOB = false;
1039 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001040 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001041 state->m_hasDVBT = true;
1042 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001043 state->m_hasSAWSW = true;
1044 state->m_hasGPIO2 = true;
1045 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001046 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001047 break;
1048 case 0x26:
1049 /* typeId = DRX3926K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001050 state->m_hasLNA = false;
1051 state->m_hasOOB = false;
1052 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001053 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001054 state->m_hasDVBT = true;
1055 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001056 state->m_hasSAWSW = true;
1057 state->m_hasGPIO2 = true;
1058 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001059 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001060 break;
1061 default:
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001062 printk(KERN_ERR "drxk: DeviceID not supported = %02x\n",
Oliver Endrissebc7de22011-07-03 13:49:44 -03001063 ((sioTopJtagidLo >> 12) & 0xFF));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001064 status = -1;
1065 break;
1066 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001067 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001068 return status;
1069}
1070
1071static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1072{
1073 int status;
1074 bool powerdown_cmd;
1075
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001076 dprintk(1, "\n");
1077
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001078 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001079 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001080 if (status < 0)
1081 return status;
1082 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1083 msleep(1);
1084
1085 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001086 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1087 ((state->m_HICfgCtrl) &
1088 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1089 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001090 if (powerdown_cmd == false) {
1091 /* Wait until command rdy */
1092 u32 retryCount = 0;
1093 u16 waitCmd;
1094
1095 do {
1096 msleep(1);
1097 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001098 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1099 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001100 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1101 && (waitCmd != 0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001102
1103 if (status == 0)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001104 status = read16(state, SIO_HI_RA_RAM_RES__A,
1105 pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001106 }
1107 return status;
1108}
1109
1110static int HI_CfgCommand(struct drxk_state *state)
1111{
1112 int status;
1113
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001114 dprintk(1, "\n");
1115
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001116 mutex_lock(&state->mutex);
1117 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001118 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
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_5__A, state->m_HICfgCtrl);
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_4__A, state->m_HICfgWakeUpKey);
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_3__A, state->m_HICfgBridgeDelay);
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_2__A, state->m_HICfgTimingDiv);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001131 if (status < 0)
1132 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001133 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 -03001134 if (status < 0)
1135 break;
1136 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1137 if (status < 0)
1138 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001139
1140 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001141 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001142 mutex_unlock(&state->mutex);
1143 return status;
1144}
1145
1146static int InitHI(struct drxk_state *state)
1147{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001148 dprintk(1, "\n");
1149
Oliver Endrissebc7de22011-07-03 13:49:44 -03001150 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001151 state->m_HICfgTimeout = 0x96FF;
1152 /* port/bridge/power down ctrl */
1153 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001154 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001155}
1156
1157static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1158{
1159 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001160 u16 sioPdrMclkCfg = 0;
1161 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001162
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001163 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001164 do {
1165 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001166 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001167 if (status < 0)
1168 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001169
1170 /* MPEG TS pad configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001171 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001172 if (status < 0)
1173 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001174
1175 if (mpegEnable == false) {
1176 /* Set MPEG TS pads to inputmode */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001177 status = write16(state, SIO_PDR_MSTRT_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_MERR_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_MCLK_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_MVAL_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_MD0_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_MD1_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_MD2_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_MD3_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_MD4_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_MD5_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_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001208 if (status < 0)
1209 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001210 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001211 if (status < 0)
1212 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001213 } else {
1214 /* Enable MPEG output */
1215 sioPdrMdxCfg =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001216 ((state->m_TSDataStrength <<
1217 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001218 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03001219 SIO_PDR_MCLK_CFG_DRIVE__B) |
1220 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001221
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001222 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
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_MERR_CFG__A, 0x0000); /* Disable */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001226 if (status < 0)
1227 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001228 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001229 if (status < 0)
1230 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001231 if (state->m_enableParallel == true) {
1232 /* paralel -> enable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001233 status = write16(state, SIO_PDR_MD1_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_MD2_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_MD3_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_MD4_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_MD5_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_MD6_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001249 if (status < 0)
1250 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001251 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001252 if (status < 0)
1253 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001254 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001255 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1256 SIO_PDR_MD0_CFG_DRIVE__B)
1257 | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001258 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001259 status = write16(state, SIO_PDR_MD1_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_MD2_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_MD3_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_MD4_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_MD5_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_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001275 if (status < 0)
1276 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001277 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001278 if (status < 0)
1279 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001280 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001281 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001282 if (status < 0)
1283 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001284 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001285 if (status < 0)
1286 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001287 }
1288 /* Enable MB output over MPEG pads and ctl input */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001289 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001290 if (status < 0)
1291 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001292 /* Write nomagic word to enable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001293 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001294 if (status < 0)
1295 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001296 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001297 return status;
1298}
1299
1300static int MPEGTSDisable(struct drxk_state *state)
1301{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001302 dprintk(1, "\n");
1303
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001304 return MPEGTSConfigurePins(state, false);
1305}
1306
1307static int BLChainCmd(struct drxk_state *state,
1308 u16 romOffset, u16 nrOfElements, u32 timeOut)
1309{
1310 u16 blStatus = 0;
1311 int status;
1312 unsigned long end;
1313
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001314 dprintk(1, "\n");
1315
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001316 mutex_lock(&state->mutex);
1317 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001318 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
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_ADDR__A, romOffset);
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_CHAIN_LEN__A, nrOfElements);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001325 if (status < 0)
1326 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001327 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001328 if (status < 0)
1329 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001330 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001331
1332 do {
1333 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001334 status = read16(state, SIO_BL_STATUS__A, &blStatus);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001335 if (status < 0)
1336 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001337 } while ((blStatus == 0x1) &&
1338 ((time_is_after_jiffies(end))));
1339 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001340 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001341 mutex_unlock(&state->mutex);
1342 return -1;
1343 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001344 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001345 mutex_unlock(&state->mutex);
1346 return status;
1347}
1348
1349
1350static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001351 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001352{
1353 const u8 *pSrc = pMCImage;
1354 u16 Flags;
1355 u16 Drain;
1356 u32 Address;
1357 u16 nBlocks;
1358 u16 BlockSize;
1359 u16 BlockCRC;
1360 u32 offset = 0;
1361 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001362 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001363
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001364 dprintk(1, "\n");
1365
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001366 /* down the drain (we don care about MAGIC_WORD) */
1367 Drain = (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 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001371 pSrc += sizeof(u16);
1372 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001373
1374 for (i = 0; i < nBlocks; i += 1) {
1375 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001376 (pSrc[2] << 8) | pSrc[3];
1377 pSrc += sizeof(u32);
1378 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001379
1380 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001381 pSrc += sizeof(u16);
1382 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001383
1384 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001385 pSrc += sizeof(u16);
1386 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001387
1388 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001389 pSrc += sizeof(u16);
1390 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001391
1392 if (offset + BlockSize > Length) {
1393 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1394 return -EINVAL;
1395 }
1396
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001397 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001398 if (status < 0) {
1399 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001400 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001401 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001402 pSrc += BlockSize;
1403 offset += BlockSize;
1404 }
1405 return status;
1406}
1407
1408static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1409{
1410 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001411 u16 data = 0;
1412 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001413 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1414 unsigned long end;
1415
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001416 dprintk(1, "\n");
1417
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001418 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001419 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001420 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1421 }
1422
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001423 status = (read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001424
1425 if (data == desiredStatus) {
1426 /* tokenring already has correct status */
1427 return status;
1428 }
1429 /* Disable/enable dvbt tokenring bridge */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001430 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001431 write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001432
Oliver Endrissebc7de22011-07-03 13:49:44 -03001433 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001434 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001435 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001436 if (status < 0)
1437 break;
1438 } while ((data != desiredStatus) && ((time_is_after_jiffies(end))));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001439 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001440 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001441 return -1;
1442 }
1443 return status;
1444}
1445
1446static int MPEGTSStop(struct drxk_state *state)
1447{
1448 int status = 0;
1449 u16 fecOcSncMode = 0;
1450 u16 fecOcIprMode = 0;
1451
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001452 dprintk(1, "\n");
1453
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001454 do {
1455 /* Gracefull shutdown (byte boundaries) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001456 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001457 if (status < 0)
1458 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001459 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001460 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001461 if (status < 0)
1462 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001463
1464 /* Suppress MCLK during absence of data */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001465 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001466 if (status < 0)
1467 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001468 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001469 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001470 if (status < 0)
1471 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001472 } while (0);
1473 return status;
1474}
1475
1476static int scu_command(struct drxk_state *state,
1477 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001478 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001479{
1480#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1481#error DRXK register mapping no longer compatible with this routine!
1482#endif
1483 u16 curCmd = 0;
1484 int status;
1485 unsigned long end;
1486
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001487 dprintk(1, "\n");
1488
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001489 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1490 ((resultLen > 0) && (result == NULL)))
1491 return -1;
1492
1493 mutex_lock(&state->mutex);
1494 do {
1495 /* assume that the command register is ready
1496 since it is checked afterwards */
1497 u8 buffer[34];
1498 int cnt = 0, ii;
1499
Oliver Endrissebc7de22011-07-03 13:49:44 -03001500 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001501 buffer[cnt++] = (parameter[ii] & 0xFF);
1502 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1503 }
1504 buffer[cnt++] = (cmd & 0xFF);
1505 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1506
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001507 write_block(state, SCU_RAM_PARAM_0__A -
1508 (parameterLen - 1), cnt, buffer);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001509 /* Wait until SCU has processed command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001510 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001511 do {
1512 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001513 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001514 if (status < 0)
1515 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001516 } while (!(curCmd == DRX_SCU_READY)
1517 && (time_is_after_jiffies(end)));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001518 if (curCmd != DRX_SCU_READY) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001519 printk(KERN_ERR "drxk: SCU not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001520 mutex_unlock(&state->mutex);
1521 return -1;
1522 }
1523 /* read results */
1524 if ((resultLen > 0) && (result != NULL)) {
1525 s16 err;
1526 int ii;
1527
Oliver Endrissebc7de22011-07-03 13:49:44 -03001528 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001529 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001530 if (status < 0)
1531 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001532 }
1533
1534 /* Check if an error was reported by SCU */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001535 err = (s16) result[0];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001536
1537 /* check a few fixed error codes */
1538 if (err == SCU_RESULT_UNKSTD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001539 printk(KERN_ERR "drxk: SCU_RESULT_UNKSTD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001540 mutex_unlock(&state->mutex);
1541 return -1;
1542 } else if (err == SCU_RESULT_UNKCMD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001543 printk(KERN_ERR "drxk: SCU_RESULT_UNKCMD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001544 mutex_unlock(&state->mutex);
1545 return -1;
1546 }
1547 /* here it is assumed that negative means error,
1548 and positive no error */
1549 else if (err < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001550 printk(KERN_ERR "drxk: %s ERROR\n", __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001551 mutex_unlock(&state->mutex);
1552 return -1;
1553 }
1554 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001555 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001556 mutex_unlock(&state->mutex);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001557 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001558 printk(KERN_ERR "drxk: %s: status = %d\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001559
1560 return status;
1561}
1562
1563static int SetIqmAf(struct drxk_state *state, bool active)
1564{
1565 u16 data = 0;
1566 int status;
1567
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001568 dprintk(1, "\n");
1569
Oliver Endrissebc7de22011-07-03 13:49:44 -03001570 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001571 /* Configure IQM */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001572 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001573 if (status < 0)
1574 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001575 if (!active) {
1576 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1577 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1578 | IQM_AF_STDBY_STDBY_PD_STANDBY
1579 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
Oliver Endrissebc7de22011-07-03 13:49:44 -03001580 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1581 } else { /* active */
1582
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001583 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1584 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1585 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1586 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1587 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
Oliver Endrissebc7de22011-07-03 13:49:44 -03001588 );
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001589 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001590 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001591 if (status < 0)
1592 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001593 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001594 return status;
1595}
1596
Oliver Endrissebc7de22011-07-03 13:49:44 -03001597static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001598{
1599 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001600 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001601
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001602 dprintk(1, "\n");
1603
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001604 /* Check arguments */
1605 if (mode == NULL)
1606 return -1;
1607
1608 switch (*mode) {
1609 case DRX_POWER_UP:
1610 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1611 break;
1612 case DRXK_POWER_DOWN_OFDM:
1613 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1614 break;
1615 case DRXK_POWER_DOWN_CORE:
1616 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1617 break;
1618 case DRXK_POWER_DOWN_PLL:
1619 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1620 break;
1621 case DRX_POWER_DOWN:
1622 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1623 break;
1624 default:
1625 /* Unknow sleep mode */
1626 return -1;
1627 break;
1628 }
1629
1630 /* If already in requested power mode, do nothing */
1631 if (state->m_currentPowerMode == *mode)
1632 return 0;
1633
1634 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001635 if (state->m_currentPowerMode != DRX_POWER_UP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001636 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001637 status = PowerUpDevice(state);
1638 if (status < 0)
1639 break;
1640 status = DVBTEnableOFDMTokenRing(state, true);
1641 if (status < 0)
1642 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001643 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001644 }
1645
1646 if (*mode == DRX_POWER_UP) {
1647 /* Restore analog & pin configuartion */
1648 } else {
1649 /* Power down to requested mode */
1650 /* Backup some register settings */
1651 /* Set pins with possible pull-ups connected
1652 to them in input mode */
1653 /* Analog power down */
1654 /* ADC power down */
1655 /* Power down device */
1656 /* stop all comm_exec */
1657 /* Stop and power down previous standard */
1658 do {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001659 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001660 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001661 status = MPEGTSStop(state);
1662 if (status < 0)
1663 break;
1664 status = PowerDownDVBT(state, false);
1665 if (status < 0)
1666 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001667 break;
1668 case OM_QAM_ITU_A:
1669 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001670 status = MPEGTSStop(state);
1671 if (status < 0)
1672 break;
1673 status = PowerDownQAM(state);
1674 if (status < 0)
1675 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001676 break;
1677 default:
1678 break;
1679 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001680 status = DVBTEnableOFDMTokenRing(state, false);
1681 if (status < 0)
1682 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001683 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001684 if (status < 0)
1685 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001686 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001687 if (status < 0)
1688 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001689
Oliver Endrissebc7de22011-07-03 13:49:44 -03001690 if (*mode != DRXK_POWER_DOWN_OFDM) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001691 state->m_HICfgCtrl |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03001692 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001693 status = HI_CfgCommand(state);
1694 if (status < 0)
1695 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001696 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001697 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001698 }
1699 state->m_currentPowerMode = *mode;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001700 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001701}
1702
1703static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1704{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001705 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001706 u16 cmdResult = 0;
1707 u16 data = 0;
1708 int status;
1709
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001710 dprintk(1, "\n");
1711
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001712 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001713 status = read16(state, SCU_COMM_EXEC__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001714 if (status < 0)
1715 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001716 if (data == SCU_COMM_EXEC_ACTIVE) {
1717 /* Send OFDM stop command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001718 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
1719 if (status < 0)
1720 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001721 /* Send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001722 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1723 if (status < 0)
1724 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001725 }
1726
1727 /* Reset datapath for OFDM, processors first */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001728 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001729 if (status < 0)
1730 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001731 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001732 if (status < 0)
1733 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001734 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001735 if (status < 0)
1736 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001737
1738 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001739 status = SetIqmAf(state, false);
1740 if (status < 0)
1741 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001742
1743 /* powerdown to OFDM mode */
1744 if (setPowerMode) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001745 status = CtrlPowerMode(state, &powerMode);
1746 if (status < 0)
1747 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001748 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001749 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001750 return status;
1751}
1752
Oliver Endrissebc7de22011-07-03 13:49:44 -03001753static int SetOperationMode(struct drxk_state *state,
1754 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001755{
1756 int status = 0;
1757
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001758 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001759 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001760 Stop and power down previous standard
1761 TODO investigate total power down instead of partial
1762 power down depending on "previous" standard.
1763 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001764 do {
1765 /* disable HW lock indicator */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001766 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001767 if (status < 0)
1768 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001769
1770 if (state->m_OperationMode != oMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001771 switch (state->m_OperationMode) {
1772 /* OM_NONE was added for start up */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001773 case OM_NONE:
1774 break;
1775 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001776 status = MPEGTSStop(state);
1777 if (status < 0)
1778 break;
1779 status = PowerDownDVBT(state, true);
1780 if (status < 0)
1781 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001782 state->m_OperationMode = OM_NONE;
1783 break;
1784 case OM_QAM_ITU_B:
1785 status = -1;
1786 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001787 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001788 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001789 status = MPEGTSStop(state);
1790 if (status < 0)
1791 break;
1792 status = PowerDownQAM(state);
1793 if (status < 0)
1794 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001795 state->m_OperationMode = OM_NONE;
1796 break;
1797 default:
1798 status = -1;
1799 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001800 status = status;
1801 if (status < 0)
1802 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001803
1804 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001805 Power up new standard
1806 */
1807 switch (oMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001808 case OM_DVBT:
1809 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001810 status = SetDVBTStandard(state, oMode);
1811 if (status < 0)
1812 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001813 break;
1814 case OM_QAM_ITU_B:
1815 status = -1;
1816 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001817 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001818 case OM_QAM_ITU_C:
1819 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001820 status = SetQAMStandard(state, oMode);
1821 if (status < 0)
1822 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001823 break;
1824 default:
1825 status = -1;
1826 }
1827 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001828 status = status;
1829 if (status < 0)
1830 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001831 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001832 return 0;
1833}
1834
1835static int Start(struct drxk_state *state, s32 offsetFreq,
1836 s32 IntermediateFrequency)
1837{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001838 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001839
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001840 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001841 do {
1842 u16 IFreqkHz;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001843 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001844
1845 if (state->m_DrxkState != DRXK_STOPPED &&
1846 state->m_DrxkState != DRXK_DTV_STARTED) {
1847 status = -1;
1848 break;
1849 }
1850 state->m_bMirrorFreqSpect =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001851 (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001852
1853 if (IntermediateFrequency < 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001854 state->m_bMirrorFreqSpect =
1855 !state->m_bMirrorFreqSpect;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001856 IntermediateFrequency = -IntermediateFrequency;
1857 }
1858
Oliver Endrissebc7de22011-07-03 13:49:44 -03001859 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001860 case OM_QAM_ITU_A:
1861 case OM_QAM_ITU_C:
1862 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001863 status = SetQAM(state, IFreqkHz, OffsetkHz);
1864 if (status < 0)
1865 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001866 state->m_DrxkState = DRXK_DTV_STARTED;
1867 break;
1868 case OM_DVBT:
1869 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001870 status = MPEGTSStop(state);
1871 if (status < 0)
1872 break;
1873 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1874 if (status < 0)
1875 break;
1876 status = DVBTStart(state);
1877 if (status < 0)
1878 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001879 state->m_DrxkState = DRXK_DTV_STARTED;
1880 break;
1881 default:
1882 break;
1883 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001884 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001885 return status;
1886}
1887
1888static int ShutDown(struct drxk_state *state)
1889{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001890 dprintk(1, "\n");
1891
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001892 MPEGTSStop(state);
1893 return 0;
1894}
1895
Oliver Endrissebc7de22011-07-03 13:49:44 -03001896static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1897 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001898{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001899 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001900
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001901 dprintk(1, "\n");
1902
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001903 if (pLockStatus == NULL)
1904 return -1;
1905
1906 *pLockStatus = NOT_LOCKED;
1907
1908 /* define the SCU command code */
1909 switch (state->m_OperationMode) {
1910 case OM_QAM_ITU_A:
1911 case OM_QAM_ITU_B:
1912 case OM_QAM_ITU_C:
1913 status = GetQAMLockStatus(state, pLockStatus);
1914 break;
1915 case OM_DVBT:
1916 status = GetDVBTLockStatus(state, pLockStatus);
1917 break;
1918 default:
1919 break;
1920 }
1921 return status;
1922}
1923
1924static int MPEGTSStart(struct drxk_state *state)
1925{
1926 int status = 0;
1927
1928 u16 fecOcSncMode = 0;
1929
1930 do {
1931 /* Allow OC to sync again */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001932 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001933 if (status < 0)
1934 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001935 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001936 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001937 if (status < 0)
1938 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001939 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001940 if (status < 0)
1941 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001942 } while (0);
1943 return status;
1944}
1945
1946static int MPEGTSDtoInit(struct drxk_state *state)
1947{
1948 int status = -1;
1949
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001950 dprintk(1, "\n");
1951
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001952 do {
1953 /* Rate integration settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001954 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001955 if (status < 0)
1956 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001957 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001958 if (status < 0)
1959 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001960 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001961 if (status < 0)
1962 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001963 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001964 if (status < 0)
1965 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001966 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001967 if (status < 0)
1968 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001969 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
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_TMD_LO_MARGIN__A, 0x0080);
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_TMD_COUNT__A, 0x03F4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001976 if (status < 0)
1977 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001978
1979 /* Additional configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001980 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001981 if (status < 0)
1982 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001983 status = write16(state, FEC_OC_SNC_LWM__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001984 if (status < 0)
1985 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001986 status = write16(state, FEC_OC_SNC_HWM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001987 if (status < 0)
1988 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001989 } while (0);
1990 return status;
1991}
1992
Oliver Endrissebc7de22011-07-03 13:49:44 -03001993static int MPEGTSDtoSetup(struct drxk_state *state,
1994 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001995{
1996 int status = -1;
1997
Oliver Endrissebc7de22011-07-03 13:49:44 -03001998 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
1999 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2000 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2001 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2002 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2003 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2004 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002005 u16 fecOcTmdMode = 0;
2006 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002007 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002008 bool staticCLK = false;
2009
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002010 dprintk(1, "\n");
2011
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002012 do {
2013 /* Check insertion of the Reed-Solomon parity bytes */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002014 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002015 if (status < 0)
2016 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002017 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002018 if (status < 0)
2019 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002020 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002021 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2022 if (state->m_insertRSByte == true) {
2023 /* enable parity symbol forward */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002024 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002025 /* MVAL disable during parity bytes */
2026 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2027 /* TS burst length to 204 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002028 fecOcDtoBurstLen = 204;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002029 }
2030
2031 /* Check serial or parrallel output */
2032 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2033 if (state->m_enableParallel == false) {
2034 /* MPEG data output is serial -> set ipr_mode[0] */
2035 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2036 }
2037
2038 switch (oMode) {
2039 case OM_DVBT:
2040 maxBitRate = state->m_DVBTBitrate;
2041 fecOcTmdMode = 3;
2042 fecOcRcnCtlRate = 0xC00000;
2043 staticCLK = state->m_DVBTStaticCLK;
2044 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002045 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002046 case OM_QAM_ITU_C:
2047 fecOcTmdMode = 0x0004;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002048 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002049 maxBitRate = state->m_DVBCBitrate;
2050 staticCLK = state->m_DVBCStaticCLK;
2051 break;
2052 default:
2053 status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002054 } /* switch (standard) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002055 status = status;
2056 if (status < 0)
2057 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002058
2059 /* Configure DTO's */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002060 if (staticCLK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002061 u32 bitRate = 0;
2062
2063 /* Rational DTO for MCLK source (static MCLK rate),
2064 Dynamic DTO for optimal grouping
2065 (avoid intra-packet gaps),
2066 DTO offset enable to sync TS burst with MSTRT */
2067 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2068 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2069 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2070 FEC_OC_FCT_MODE_VIRT_ENA__M);
2071
2072 /* Check user defined bitrate */
2073 bitRate = maxBitRate;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002074 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002075 bitRate = 75900000UL;
2076 }
2077 /* Rational DTO period:
2078 dto_period = (Fsys / bitrate) - 2
2079
2080 Result should be floored,
2081 to make sure >= requested bitrate
Oliver Endrissebc7de22011-07-03 13:49:44 -03002082 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002083 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2084 * 1000) / bitRate);
2085 if (fecOcDtoPeriod <= 2)
2086 fecOcDtoPeriod = 0;
2087 else
2088 fecOcDtoPeriod -= 2;
2089 fecOcTmdIntUpdRate = 8;
2090 } else {
2091 /* (commonAttr->staticCLK == false) => dynamic mode */
2092 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2093 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2094 fecOcTmdIntUpdRate = 5;
2095 }
2096
2097 /* Write appropriate registers with requested configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002098 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002099 if (status < 0)
2100 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002101 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002102 if (status < 0)
2103 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002104 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002105 if (status < 0)
2106 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002107 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
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_MODE__A, fecOcRegMode);
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_IPR_MODE__A, fecOcRegIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002114 if (status < 0)
2115 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002116
2117 /* Rate integration settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002118 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002119 if (status < 0)
2120 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002121 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002122 if (status < 0)
2123 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002124 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002125 if (status < 0)
2126 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002127 } while (0);
2128 return status;
2129}
2130
2131static int MPEGTSConfigurePolarity(struct drxk_state *state)
2132{
2133 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002134 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002135
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002136 dprintk(1, "\n");
2137
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002138 /* Data mask for the output data byte */
2139 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002140 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2141 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2142 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2143 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002144
2145 /* Control selective inversion of output bits */
2146 fecOcRegIprInvert &= (~(InvertDataMask));
2147 if (state->m_invertDATA == true)
2148 fecOcRegIprInvert |= InvertDataMask;
2149 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2150 if (state->m_invertERR == true)
2151 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2152 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2153 if (state->m_invertSTR == true)
2154 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2155 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2156 if (state->m_invertVAL == true)
2157 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2158 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2159 if (state->m_invertCLK == true)
2160 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002161 status = write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002162 return status;
2163}
2164
2165#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2166
2167static int SetAgcRf(struct drxk_state *state,
2168 struct SCfgAgc *pAgcCfg, bool isDTV)
2169{
2170 int status = 0;
2171 struct SCfgAgc *pIfAgcSettings;
2172
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002173 dprintk(1, "\n");
2174
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002175 if (pAgcCfg == NULL)
2176 return -1;
2177
2178 do {
2179 u16 data = 0;
2180
2181 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002182 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002183
2184 /* Enable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002185 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002186 if (status < 0)
2187 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002188 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002189 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002190 if (status < 0)
2191 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002192
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002193 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002194 if (status < 0)
2195 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002196
2197 /* Enable SCU RF AGC loop */
2198 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2199
2200 /* Polarity */
2201 if (state->m_RfAgcPol)
2202 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2203 else
2204 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002205 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002206 if (status < 0)
2207 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002208
2209 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002210 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002211 if (status < 0)
2212 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002213
2214 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2215 data |= (~(pAgcCfg->speed <<
2216 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2217 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2218
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002219 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002220 if (status < 0)
2221 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002222
2223 if (IsDVBT(state))
2224 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2225 else if (IsQAM(state))
2226 pIfAgcSettings = &state->m_qamIfAgcCfg;
2227 else
2228 pIfAgcSettings = &state->m_atvIfAgcCfg;
2229 if (pIfAgcSettings == NULL)
2230 return -1;
2231
2232 /* Set TOP, only if IF-AGC is in AUTO mode */
2233 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002234 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002235 if (status < 0)
2236 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002237
2238 /* Cut-Off current */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002239 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002240 if (status < 0)
2241 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002242
2243 /* Max. output level */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002244 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002245 if (status < 0)
2246 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002247
2248 break;
2249
2250 case DRXK_AGC_CTRL_USER:
2251 /* Enable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002252 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002253 if (status < 0)
2254 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002255 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002256 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002257 if (status < 0)
2258 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002259
2260 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002261 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002262 if (status < 0)
2263 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002264 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2265 if (state->m_RfAgcPol)
2266 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2267 else
2268 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002269 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002270 if (status < 0)
2271 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002272
2273 /* SCU c.o.c. to 0, enabling full control range */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002274 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002275 if (status < 0)
2276 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002277
2278 /* Write value to output pin */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002279 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002280 if (status < 0)
2281 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002282 break;
2283
Oliver Endrissebc7de22011-07-03 13:49:44 -03002284 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002285 /* Disable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002286 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002287 if (status < 0)
2288 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002289 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002290 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002291 if (status < 0)
2292 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002293
2294 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002295 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002296 if (status < 0)
2297 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002298 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002299 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002300 if (status < 0)
2301 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002302 break;
2303
2304 default:
2305 return -1;
2306
Oliver Endrissebc7de22011-07-03 13:49:44 -03002307 } /* switch (agcsettings->ctrlMode) */
2308 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002309 return status;
2310}
2311
2312#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2313
Oliver Endrissebc7de22011-07-03 13:49:44 -03002314static int SetAgcIf(struct drxk_state *state,
2315 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002316{
2317 u16 data = 0;
2318 int status = 0;
2319 struct SCfgAgc *pRfAgcSettings;
2320
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002321 dprintk(1, "\n");
2322
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002323 do {
2324 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002325 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002326
2327 /* Enable IF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002328 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002329 if (status < 0)
2330 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002331 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002332 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002333 if (status < 0)
2334 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002335
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002336 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002337 if (status < 0)
2338 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002339
2340 /* Enable SCU IF AGC loop */
2341 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2342
2343 /* Polarity */
2344 if (state->m_IfAgcPol)
2345 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2346 else
2347 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002348 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002349 if (status < 0)
2350 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002351
2352 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002353 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002354 if (status < 0)
2355 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002356 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2357 data |= (~(pAgcCfg->speed <<
2358 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2359 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2360
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002361 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002362 if (status < 0)
2363 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002364
2365 if (IsQAM(state))
2366 pRfAgcSettings = &state->m_qamRfAgcCfg;
2367 else
2368 pRfAgcSettings = &state->m_atvRfAgcCfg;
2369 if (pRfAgcSettings == NULL)
2370 return -1;
2371 /* Restore TOP */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002372 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002373 if (status < 0)
2374 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002375 break;
2376
Oliver Endrissebc7de22011-07-03 13:49:44 -03002377 case DRXK_AGC_CTRL_USER:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002378
2379 /* Enable IF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002380 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002381 if (status < 0)
2382 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002383 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002384 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002385 if (status < 0)
2386 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002387
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002388 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002389 if (status < 0)
2390 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002391
2392 /* Disable SCU IF AGC loop */
2393 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2394
2395 /* Polarity */
2396 if (state->m_IfAgcPol)
2397 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2398 else
2399 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002400 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002401 if (status < 0)
2402 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002403
2404 /* Write value to output pin */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002405 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002406 if (status < 0)
2407 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002408 break;
2409
Oliver Endrissebc7de22011-07-03 13:49:44 -03002410 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002411
2412 /* Disable If AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002413 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002414 if (status < 0)
2415 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002416 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002417 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002418 if (status < 0)
2419 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002420
2421 /* Disable SCU IF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002422 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002423 if (status < 0)
2424 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002425 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002426 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002427 if (status < 0)
2428 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002429 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002430 } /* switch (agcSettingsIf->ctrlMode) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002431
2432 /* always set the top to support
2433 configurations without if-loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002434 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002435 if (status < 0)
2436 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002437
2438
Oliver Endrissebc7de22011-07-03 13:49:44 -03002439 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002440 return status;
2441}
2442
2443static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2444{
2445 u16 agcDacLvl;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002446 int status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002447
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002448 dprintk(1, "\n");
2449
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002450 *pValue = 0;
2451
Oliver Endrissebc7de22011-07-03 13:49:44 -03002452 if (status == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002453 u16 Level = 0;
2454 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2455 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2456 if (Level < 14000)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002457 *pValue = (14000 - Level) / 4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002458 else
2459 *pValue = 0;
2460 }
2461 return status;
2462}
2463
Oliver Endrissebc7de22011-07-03 13:49:44 -03002464static int GetQAMSignalToNoise(struct drxk_state *state,
2465 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002466{
2467 int status = 0;
2468
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002469 dprintk(1, "\n");
2470
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002471 do {
2472 /* MER calculation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002473 u16 qamSlErrPower = 0; /* accum. error between
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002474 raw and sliced symbols */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002475 u32 qamSlSigPower = 0; /* used for MER, depends of
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002476 QAM constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002477 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002478
2479 /* get the register value needed for MER */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002480 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002481 if (status < 0)
2482 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002483
Oliver Endrissebc7de22011-07-03 13:49:44 -03002484 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002485 case QAM_16:
2486 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2487 break;
2488 case QAM_32:
2489 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2490 break;
2491 case QAM_64:
2492 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2493 break;
2494 case QAM_128:
2495 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2496 break;
2497 default:
2498 case QAM_256:
2499 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2500 break;
2501 }
2502
2503 if (qamSlErrPower > 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002504 qamSlMer = Log10Times100(qamSlSigPower) -
2505 Log10Times100((u32) qamSlErrPower);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002506 }
2507 *pSignalToNoise = qamSlMer;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002508 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002509 return status;
2510}
2511
Oliver Endrissebc7de22011-07-03 13:49:44 -03002512static int GetDVBTSignalToNoise(struct drxk_state *state,
2513 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002514{
2515 int status = 0;
2516
Oliver Endrissebc7de22011-07-03 13:49:44 -03002517 u16 regData = 0;
2518 u32 EqRegTdSqrErrI = 0;
2519 u32 EqRegTdSqrErrQ = 0;
2520 u16 EqRegTdSqrErrExp = 0;
2521 u16 EqRegTdTpsPwrOfs = 0;
2522 u16 EqRegTdReqSmbCnt = 0;
2523 u32 tpsCnt = 0;
2524 u32 SqrErrIQ = 0;
2525 u32 a = 0;
2526 u32 b = 0;
2527 u32 c = 0;
2528 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002529 u16 transmissionParams = 0;
2530
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002531 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002532 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002533 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002534 if (status < 0)
2535 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002536 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002537 if (status < 0)
2538 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002539 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002540 if (status < 0)
2541 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002542 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002543 if (status < 0)
2544 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002545 /* Extend SQR_ERR_I operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002546 EqRegTdSqrErrI = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002547 if ((EqRegTdSqrErrExp > 11) &&
2548 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2549 EqRegTdSqrErrI += 0x00010000UL;
2550 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002551 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002552 if (status < 0)
2553 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002554 /* Extend SQR_ERR_Q operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002555 EqRegTdSqrErrQ = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002556 if ((EqRegTdSqrErrExp > 11) &&
2557 (EqRegTdSqrErrQ < 0x00000FFFUL))
2558 EqRegTdSqrErrQ += 0x00010000UL;
2559
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002560 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002561 if (status < 0)
2562 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002563
2564 /* Check input data for MER */
2565
2566 /* MER calculation (in 0.1 dB) without math.h */
2567 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2568 iMER = 0;
2569 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2570 /* No error at all, this must be the HW reset value
2571 * Apparently no first measurement yet
2572 * Set MER to 0.0 */
2573 iMER = 0;
2574 } else {
2575 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03002576 EqRegTdSqrErrExp;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002577 if ((transmissionParams &
2578 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2579 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2580 tpsCnt = 17;
2581 else
2582 tpsCnt = 68;
2583
2584 /* IMER = 100 * log10 (x)
2585 where x = (EqRegTdTpsPwrOfs^2 *
2586 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2587
2588 => IMER = a + b -c
2589 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2590 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2591 c = 100 * log10 (SqrErrIQ)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002592 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002593
2594 /* log(x) x = 9bits * 9bits->18 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002595 a = Log10Times100(EqRegTdTpsPwrOfs *
2596 EqRegTdTpsPwrOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002597 /* log(x) x = 16bits * 7bits->23 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002598 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002599 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2600 c = Log10Times100(SqrErrIQ);
2601
2602 iMER = a + b;
2603 /* No negative MER, clip to zero */
2604 if (iMER > c)
2605 iMER -= c;
2606 else
2607 iMER = 0;
2608 }
2609 *pSignalToNoise = iMER;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002610 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002611
2612 return status;
2613}
2614
2615static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2616{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002617 dprintk(1, "\n");
2618
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002619 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002620 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002621 case OM_DVBT:
2622 return GetDVBTSignalToNoise(state, pSignalToNoise);
2623 case OM_QAM_ITU_A:
2624 case OM_QAM_ITU_C:
2625 return GetQAMSignalToNoise(state, pSignalToNoise);
2626 default:
2627 break;
2628 }
2629 return 0;
2630}
2631
2632#if 0
2633static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2634{
2635 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2636 int status = 0;
2637
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002638 dprintk(1, "\n");
2639
Oliver Endrissebc7de22011-07-03 13:49:44 -03002640 static s32 QE_SN[] = {
2641 51, /* QPSK 1/2 */
2642 69, /* QPSK 2/3 */
2643 79, /* QPSK 3/4 */
2644 89, /* QPSK 5/6 */
2645 97, /* QPSK 7/8 */
2646 108, /* 16-QAM 1/2 */
2647 131, /* 16-QAM 2/3 */
2648 146, /* 16-QAM 3/4 */
2649 156, /* 16-QAM 5/6 */
2650 160, /* 16-QAM 7/8 */
2651 165, /* 64-QAM 1/2 */
2652 187, /* 64-QAM 2/3 */
2653 202, /* 64-QAM 3/4 */
2654 216, /* 64-QAM 5/6 */
2655 225, /* 64-QAM 7/8 */
2656 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002657
2658 *pQuality = 0;
2659
2660 do {
2661 s32 SignalToNoise = 0;
2662 u16 Constellation = 0;
2663 u16 CodeRate = 0;
2664 u32 SignalToNoiseRel;
2665 u32 BERQuality;
2666
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002667 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2668 if (status < 0)
2669 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002670 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002671 if (status < 0)
2672 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002673 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2674
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002675 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002676 if (status < 0)
2677 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002678 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2679
2680 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2681 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2682 break;
2683 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002684 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002685 BERQuality = 100;
2686
Oliver Endrissebc7de22011-07-03 13:49:44 -03002687 if (SignalToNoiseRel < -70)
2688 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002689 else if (SignalToNoiseRel < 30)
2690 *pQuality = ((SignalToNoiseRel + 70) *
2691 BERQuality) / 100;
2692 else
2693 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002694 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002695 return 0;
2696};
2697
Oliver Endrissebc7de22011-07-03 13:49:44 -03002698static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002699{
2700 int status = 0;
2701 *pQuality = 0;
2702
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002703 dprintk(1, "\n");
2704
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002705 do {
2706 u32 SignalToNoise = 0;
2707 u32 BERQuality = 100;
2708 u32 SignalToNoiseRel = 0;
2709
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002710 status = GetQAMSignalToNoise(state, &SignalToNoise);
2711 if (status < 0)
2712 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002713
Oliver Endrissebc7de22011-07-03 13:49:44 -03002714 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002715 case QAM_16:
2716 SignalToNoiseRel = SignalToNoise - 200;
2717 break;
2718 case QAM_32:
2719 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002720 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002721 case QAM_64:
2722 SignalToNoiseRel = SignalToNoise - 260;
2723 break;
2724 case QAM_128:
2725 SignalToNoiseRel = SignalToNoise - 290;
2726 break;
2727 default:
2728 case QAM_256:
2729 SignalToNoiseRel = SignalToNoise - 320;
2730 break;
2731 }
2732
2733 if (SignalToNoiseRel < -70)
2734 *pQuality = 0;
2735 else if (SignalToNoiseRel < 30)
2736 *pQuality = ((SignalToNoiseRel + 70) *
2737 BERQuality) / 100;
2738 else
2739 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002740 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002741
2742 return status;
2743}
2744
2745static int GetQuality(struct drxk_state *state, s32 *pQuality)
2746{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002747 dprintk(1, "\n");
2748
Oliver Endrissebc7de22011-07-03 13:49:44 -03002749 switch (state->m_OperationMode) {
2750 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002751 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002752 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002753 return GetDVBCQuality(state, pQuality);
2754 default:
2755 break;
2756 }
2757
2758 return 0;
2759}
2760#endif
2761
2762/* Free data ram in SIO HI */
2763#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2764#define SIO_HI_RA_RAM_USR_END__A 0x420060
2765
2766#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2767#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2768#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2769#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2770
2771#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2772#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2773#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2774
2775static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2776{
2777 int status;
2778
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002779 dprintk(1, "\n");
2780
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002781 if (state->m_DrxkState == DRXK_UNINITIALIZED)
2782 return -1;
2783 if (state->m_DrxkState == DRXK_POWERED_DOWN)
2784 return -1;
2785
2786 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002787 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 -03002788 if (status < 0)
2789 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002790 if (bEnableBridge) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002791 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 -03002792 if (status < 0)
2793 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002794 } else {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002795 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 -03002796 if (status < 0)
2797 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002798 }
2799
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002800 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2801 if (status < 0)
2802 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002803 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002804 return status;
2805}
2806
Oliver Endrissebc7de22011-07-03 13:49:44 -03002807static int SetPreSaw(struct drxk_state *state,
2808 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002809{
2810 int status;
2811
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002812 dprintk(1, "\n");
2813
Oliver Endrissebc7de22011-07-03 13:49:44 -03002814 if ((pPreSawCfg == NULL)
2815 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002816 return -1;
2817
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002818 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002819 return status;
2820}
2821
2822static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002823 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002824{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002825 u16 blStatus = 0;
2826 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2827 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2828 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002829 unsigned long end;
2830
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002831 dprintk(1, "\n");
2832
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002833 mutex_lock(&state->mutex);
2834 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002835 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002836 if (status < 0)
2837 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002838 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002839 if (status < 0)
2840 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002841 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002842 if (status < 0)
2843 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002844 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002845 if (status < 0)
2846 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002847 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002848 if (status < 0)
2849 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002850 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002851 if (status < 0)
2852 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002853
Oliver Endrissebc7de22011-07-03 13:49:44 -03002854 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002855 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002856 status = read16(state, SIO_BL_STATUS__A, &blStatus);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002857 if (status < 0)
2858 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002859 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002860 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03002861 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002862 mutex_unlock(&state->mutex);
2863 return -1;
2864 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03002865 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002866 mutex_unlock(&state->mutex);
2867 return status;
2868
2869}
2870
Oliver Endrissebc7de22011-07-03 13:49:44 -03002871static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002872{
2873 u16 data = 0;
2874 int status;
2875
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002876 dprintk(1, "\n");
2877
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002878 do {
2879 /* Start measurement */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002880 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002881 if (status < 0)
2882 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002883 status = write16(state, IQM_AF_START_LOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002884 if (status < 0)
2885 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002886
2887 *count = 0;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002888 status = read16(state, IQM_AF_PHASE0__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002889 if (status < 0)
2890 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002891 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002892 *count = *count + 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002893 status = read16(state, IQM_AF_PHASE1__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002894 if (status < 0)
2895 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002896 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002897 *count = *count + 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002898 status = read16(state, IQM_AF_PHASE2__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002899 if (status < 0)
2900 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002901 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002902 *count = *count + 1;
2903 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002904 return status;
2905}
2906
2907static int ADCSynchronization(struct drxk_state *state)
2908{
2909 u16 count = 0;
2910 int status;
2911
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002912 dprintk(1, "\n");
2913
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002914 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002915 status = ADCSyncMeasurement(state, &count);
2916 if (status < 0)
2917 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002918
Oliver Endrissebc7de22011-07-03 13:49:44 -03002919 if (count == 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002920 /* Try sampling on a diffrent edge */
2921 u16 clkNeg = 0;
2922
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002923 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002924 if (status < 0)
2925 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002926 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002927 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2928 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2929 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002930 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002931 } else {
2932 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2933 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002934 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002935 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002936 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002937 if (status < 0)
2938 break;
2939 status = ADCSyncMeasurement(state, &count);
2940 if (status < 0)
2941 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002942 }
2943
2944 if (count < 2)
2945 status = -1;
2946 } while (0);
2947 return status;
2948}
2949
2950static int SetFrequencyShifter(struct drxk_state *state,
2951 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002952 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002953{
2954 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002955 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002956 u32 fmFrequencyShift = 0;
2957 bool tunerMirror = !state->m_bMirrorFreqSpect;
2958 u32 adcFreq;
2959 bool adcFlip;
2960 int status;
2961 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002962 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002963 u32 frequencyShift;
2964 bool imageToSelect;
2965
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002966 dprintk(1, "\n");
2967
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002968 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03002969 Program frequency shifter
2970 No need to account for mirroring on RF
2971 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002972 if (isDTV) {
2973 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
2974 (state->m_OperationMode == OM_QAM_ITU_C) ||
2975 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03002976 selectPosImage = true;
2977 else
2978 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002979 }
2980 if (tunerMirror)
2981 /* tuner doesn't mirror */
2982 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03002983 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002984 else
2985 /* tuner mirrors */
2986 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002987 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002988 if (ifFreqActual > samplingFrequency / 2) {
2989 /* adc mirrors */
2990 adcFreq = samplingFrequency - ifFreqActual;
2991 adcFlip = true;
2992 } else {
2993 /* adc doesn't mirror */
2994 adcFreq = ifFreqActual;
2995 adcFlip = false;
2996 }
2997
2998 frequencyShift = adcFreq;
2999 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003000 adcFlip ^ selectPosImage;
3001 state->m_IqmFsRateOfs =
3002 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003003
3004 if (imageToSelect)
3005 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3006
3007 /* Program frequency shifter with tuner offset compensation */
3008 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003009 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3010 state->m_IqmFsRateOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003011 return status;
3012}
3013
3014static int InitAGC(struct drxk_state *state, bool isDTV)
3015{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003016 u16 ingainTgt = 0;
3017 u16 ingainTgtMin = 0;
3018 u16 ingainTgtMax = 0;
3019 u16 clpCyclen = 0;
3020 u16 clpSumMin = 0;
3021 u16 clpDirTo = 0;
3022 u16 snsSumMin = 0;
3023 u16 snsSumMax = 0;
3024 u16 clpSumMax = 0;
3025 u16 snsDirTo = 0;
3026 u16 kiInnergainMin = 0;
3027 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003028 u16 ifIaccuHiTgtMin = 0;
3029 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003030 u16 data = 0;
3031 u16 fastClpCtrlDelay = 0;
3032 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003033 int status = 0;
3034
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003035 dprintk(1, "\n");
3036
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003037 do {
3038 /* Common settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003039 snsSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003040 ifIaccuHiTgtMin = 2047;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003041 clpCyclen = 500;
3042 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003043
3044 if (IsQAM(state)) {
3045 /* Standard specific settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003046 clpSumMin = 8;
3047 clpDirTo = (u16) -9;
3048 clpCtrlMode = 0;
3049 snsSumMin = 8;
3050 snsDirTo = (u16) -9;
3051 kiInnergainMin = (u16) -1030;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003052 } else
3053 status = -1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003054 status = (status);
3055 if (status < 0)
3056 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003057 if (IsQAM(state)) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003058 ifIaccuHiTgtMax = 0x2380;
3059 ifIaccuHiTgt = 0x2380;
3060 ingainTgtMin = 0x0511;
3061 ingainTgt = 0x0511;
3062 ingainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003063 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003064 state->m_qamIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003065 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003066 ifIaccuHiTgtMax = 0x1200;
3067 ifIaccuHiTgt = 0x1200;
3068 ingainTgtMin = 13424;
3069 ingainTgt = 13424;
3070 ingainTgtMax = 30000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003071 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003072 state->m_dvbtIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003073 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003074 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003075 if (status < 0)
3076 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003077
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003078 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003079 if (status < 0)
3080 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003081 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003082 if (status < 0)
3083 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003084 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003085 if (status < 0)
3086 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003087 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003088 if (status < 0)
3089 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003090 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003091 if (status < 0)
3092 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003093 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003094 if (status < 0)
3095 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003096 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003097 if (status < 0)
3098 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003099 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003100 if (status < 0)
3101 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003102 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003103 if (status < 0)
3104 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003105 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003106 if (status < 0)
3107 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003108 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003109 if (status < 0)
3110 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003111 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003112 if (status < 0)
3113 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003114
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003115 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003116 if (status < 0)
3117 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003118 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003119 if (status < 0)
3120 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003121 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003122 if (status < 0)
3123 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003124
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003125 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003126 if (status < 0)
3127 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003128 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003129 if (status < 0)
3130 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003131 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003132 if (status < 0)
3133 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003134
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003135 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003136 if (status < 0)
3137 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003138 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003139 if (status < 0)
3140 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003141 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003142 if (status < 0)
3143 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003144 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003145 if (status < 0)
3146 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003147 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003148 if (status < 0)
3149 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003150 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003151 if (status < 0)
3152 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003153 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003154 if (status < 0)
3155 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003156 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003157 if (status < 0)
3158 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003159 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003160 if (status < 0)
3161 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003162 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003163 if (status < 0)
3164 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003165 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003166 if (status < 0)
3167 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003168 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003169 if (status < 0)
3170 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003171 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003172 if (status < 0)
3173 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003174 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003175 if (status < 0)
3176 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003177 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003178 if (status < 0)
3179 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003180 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003181 if (status < 0)
3182 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003183 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003184 if (status < 0)
3185 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003186 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003187 if (status < 0)
3188 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003189 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003190 if (status < 0)
3191 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003192
3193 /* Initialize inner-loop KI gain factors */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003194 status = read16(state, SCU_RAM_AGC_KI__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003195 if (status < 0)
3196 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003197 if (IsQAM(state)) {
3198 data = 0x0657;
3199 data &= ~SCU_RAM_AGC_KI_RF__M;
3200 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3201 data &= ~SCU_RAM_AGC_KI_IF__M;
3202 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3203 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003204 status = write16(state, SCU_RAM_AGC_KI__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003205 if (status < 0)
3206 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003207 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003208 return status;
3209}
3210
Oliver Endrissebc7de22011-07-03 13:49:44 -03003211static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003212{
3213 int status;
3214
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003215 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003216 do {
3217 if (packetErr == NULL) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003218 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003219 if (status < 0)
3220 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003221 } else {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003222 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003223 if (status < 0)
3224 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003225 }
3226 } while (0);
3227 return status;
3228}
3229
3230static int DVBTScCommand(struct drxk_state *state,
3231 u16 cmd, u16 subcmd,
3232 u16 param0, u16 param1, u16 param2,
3233 u16 param3, u16 param4)
3234{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003235 u16 curCmd = 0;
3236 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003237 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003238 u16 scExec = 0;
3239 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003240
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003241 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003242 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003243 if (scExec != 1) {
3244 /* SC is not running */
3245 return -1;
3246 }
3247
3248 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003249 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003250 do {
3251 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003252 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003253 retryCnt++;
3254 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
3255 if (retryCnt >= DRXK_MAX_RETRIES)
3256 return -1;
3257 /* Write sub-command */
3258 switch (cmd) {
3259 /* All commands using sub-cmd */
3260 case OFDM_SC_RA_RAM_CMD_PROC_START:
3261 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3262 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003263 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003264 write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003265 break;
3266 default:
3267 /* Do nothing */
3268 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003269 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003270
3271 /* Write needed parameters and the command */
3272 switch (cmd) {
3273 /* All commands using 5 parameters */
3274 /* All commands using 4 parameters */
3275 /* All commands using 3 parameters */
3276 /* All commands using 2 parameters */
3277 case OFDM_SC_RA_RAM_CMD_PROC_START:
3278 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3279 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003280 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003281 write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003282 /* All commands using 1 parameters */
3283 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3284 case OFDM_SC_RA_RAM_CMD_USER_IO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003285 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003286 write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003287 /* All commands using 0 parameters */
3288 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3289 case OFDM_SC_RA_RAM_CMD_NULL:
3290 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003291 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003292 break;
3293 default:
3294 /* Unknown command */
3295 return -EINVAL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003296 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003297
3298 /* Wait until sc is ready processing command */
3299 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003300 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003301 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003302 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003303 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003304 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003305 if (retryCnt >= DRXK_MAX_RETRIES)
3306 return -1;
3307
3308 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003309 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003310 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003311 /* illegal command */
3312 return -EINVAL;
3313 }
3314
3315 /* Retreive results parameters from SC */
3316 switch (cmd) {
3317 /* All commands yielding 5 results */
3318 /* All commands yielding 4 results */
3319 /* All commands yielding 3 results */
3320 /* All commands yielding 2 results */
3321 /* All commands yielding 1 result */
3322 case OFDM_SC_RA_RAM_CMD_USER_IO:
3323 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003324 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003325 read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003326 /* All commands yielding 0 results */
3327 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3328 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3329 case OFDM_SC_RA_RAM_CMD_PROC_START:
3330 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3331 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3332 case OFDM_SC_RA_RAM_CMD_NULL:
3333 break;
3334 default:
3335 /* Unknown command */
3336 return -EINVAL;
3337 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003338 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003339 return status;
3340}
3341
Oliver Endrissebc7de22011-07-03 13:49:44 -03003342static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003343{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003344 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003345 int status;
3346
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003347 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003348 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003349 status = CtrlPowerMode(state, &powerMode);
3350 if (status < 0)
3351 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003352 } while (0);
3353 return status;
3354}
3355
Oliver Endrissebc7de22011-07-03 13:49:44 -03003356static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003357{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003358 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003359
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003360 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003361 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003362 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003363 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003364 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003365
3366 return status;
3367}
3368
3369#define DEFAULT_FR_THRES_8K 4000
3370static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3371{
3372
3373 int status;
3374
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003375 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003376 if (*enabled == true) {
3377 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003378 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003379 DEFAULT_FR_THRES_8K);
3380 } else {
3381 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003382 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003383 }
3384
3385 return status;
3386}
3387
3388static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3389 struct DRXKCfgDvbtEchoThres_t *echoThres)
3390{
3391 u16 data = 0;
3392 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003393
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003394 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003395 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003396 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003397 if (status < 0)
3398 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003399
Oliver Endrissebc7de22011-07-03 13:49:44 -03003400 switch (echoThres->fftMode) {
3401 case DRX_FFTMODE_2K:
3402 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3403 data |=
3404 ((echoThres->threshold <<
3405 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3406 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3407 break;
3408 case DRX_FFTMODE_8K:
3409 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3410 data |=
3411 ((echoThres->threshold <<
3412 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3413 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3414 break;
3415 default:
3416 return -1;
3417 break;
3418 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003419
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003420 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003421 if (status < 0)
3422 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003423 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003424
Oliver Endrissebc7de22011-07-03 13:49:44 -03003425 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003426}
3427
3428static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003429 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003430{
3431 int status;
3432
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003433 dprintk(1, "\n");
3434
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003435 switch (*speed) {
3436 case DRXK_DVBT_SQI_SPEED_FAST:
3437 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3438 case DRXK_DVBT_SQI_SPEED_SLOW:
3439 break;
3440 default:
3441 return -EINVAL;
3442 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003443 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003444 (u16) *speed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003445 return status;
3446}
3447
3448/*============================================================================*/
3449
3450/**
3451* \brief Activate DVBT specific presets
3452* \param demod instance of demodulator.
3453* \return DRXStatus_t.
3454*
3455* Called in DVBTSetStandard
3456*
3457*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003458static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003459{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003460 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003461
Oliver Endrissebc7de22011-07-03 13:49:44 -03003462 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3463 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003464
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003465 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003466 do {
3467 bool setincenable = false;
3468 bool setfrenable = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003469 status = DVBTCtrlSetIncEnable(state, &setincenable);
3470 if (status < 0)
3471 break;
3472 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3473 if (status < 0)
3474 break;
3475 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3476 if (status < 0)
3477 break;
3478 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3479 if (status < 0)
3480 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003481 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003482 if (status < 0)
3483 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003484 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003485
Oliver Endrissebc7de22011-07-03 13:49:44 -03003486 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003487}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003488
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003489/*============================================================================*/
3490
3491/**
3492* \brief Initialize channelswitch-independent settings for DVBT.
3493* \param demod instance of demodulator.
3494* \return DRXStatus_t.
3495*
3496* For ROM code channel filter taps are loaded from the bootloader. For microcode
3497* the DVB-T taps from the drxk_filters.h are used.
3498*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003499static int SetDVBTStandard(struct drxk_state *state,
3500 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003501{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003502 u16 cmdResult = 0;
3503 u16 data = 0;
3504 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003505
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003506 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003507
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003508 PowerUpDVBT(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003509 do {
3510 /* added antenna switch */
3511 SwitchAntennaToDVBT(state);
3512 /* send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003513 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
3514 if (status < 0)
3515 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003516
3517 /* send OFDM setenv command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003518 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3519 if (status < 0)
3520 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003521
3522 /* reset datapath for OFDM, processors first */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003523 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003524 if (status < 0)
3525 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003526 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003527 if (status < 0)
3528 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003529 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003530 if (status < 0)
3531 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003532
3533 /* IQM setup */
3534 /* synchronize on ofdstate->m_festart */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003535 status = write16(state, IQM_AF_UPD_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003536 if (status < 0)
3537 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003538 /* window size for clipping ADC detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003539 status = write16(state, IQM_AF_CLP_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003540 if (status < 0)
3541 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003542 /* window size for for sense pre-SAW detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003543 status = write16(state, IQM_AF_SNS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003544 if (status < 0)
3545 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003546 /* sense threshold for sense pre-SAW detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003547 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003548 if (status < 0)
3549 break;
3550 status = SetIqmAf(state, true);
3551 if (status < 0)
3552 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003553
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003554 status = write16(state, IQM_AF_AGC_RF__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003555 if (status < 0)
3556 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003557
3558 /* Impulse noise cruncher setup */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003559 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003560 if (status < 0)
3561 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003562 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003563 if (status < 0)
3564 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003565 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003566 if (status < 0)
3567 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003568
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003569 status = write16(state, IQM_RC_STRETCH__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003570 if (status < 0)
3571 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003572 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003573 if (status < 0)
3574 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003575 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
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_SCALE__A, 1600);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003579 if (status < 0)
3580 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003581 status = write16(state, IQM_CF_SCALE_SH__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003582 if (status < 0)
3583 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003584
3585 /* virtual clipping threshold for clipping ADC detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003586 status = write16(state, IQM_AF_CLP_TH__A, 448);
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_DATATH__A, 495); /* crunching threshold */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003590 if (status < 0)
3591 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003592
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003593 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3594 if (status < 0)
3595 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003596
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003597 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003598 if (status < 0)
3599 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003600 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003601 if (status < 0)
3602 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003603 /* enable power measurement interrupt */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003604 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003605 if (status < 0)
3606 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003607 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003608 if (status < 0)
3609 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003610
3611 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003612 status = ADCSynchronization(state);
3613 if (status < 0)
3614 break;
3615 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3616 if (status < 0)
3617 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003618
3619 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003620 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003621 if (status < 0)
3622 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003623
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003624 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3625 if (status < 0)
3626 break;
3627 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3628 if (status < 0)
3629 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003630
3631 /* Set Noise Estimation notch width and enable DC fix */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003632 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003633 if (status < 0)
3634 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003635 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003636 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003637 if (status < 0)
3638 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003639
3640 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003641 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003642 if (status < 0)
3643 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003644
Oliver Endrissebc7de22011-07-03 13:49:44 -03003645 if (!state->m_DRXK_A3_ROM_CODE) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003646 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003647 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003648 if (status < 0)
3649 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003650 }
3651
3652 /* OFDM_SC setup */
3653#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003654 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003655 if (status < 0)
3656 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003657 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003658 if (status < 0)
3659 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003660#endif
3661
3662 /* FEC setup */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003663 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003664 if (status < 0)
3665 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003666
3667
3668#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003669 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003670 if (status < 0)
3671 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003672#else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003673 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003674 if (status < 0)
3675 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003676#endif
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003677 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003678 if (status < 0)
3679 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003680
3681 /* Setup MPEG bus */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003682 status = MPEGTSDtoSetup(state, OM_DVBT);
3683 if (status < 0)
3684 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003685 /* Set DVBT Presets */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003686 status = DVBTActivatePresets(state);
3687 if (status < 0)
3688 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003689
3690 } while (0);
3691
Oliver Endrissebc7de22011-07-03 13:49:44 -03003692 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003693 printk(KERN_ERR "drxk: %s status - %08x\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003694
3695 return status;
3696}
3697
3698/*============================================================================*/
3699/**
3700* \brief Start dvbt demodulating for channel.
3701* \param demod instance of demodulator.
3702* \return DRXStatus_t.
3703*/
3704static int DVBTStart(struct drxk_state *state)
3705{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003706 u16 param1;
3707 int status;
3708 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003709
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003710 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003711 /* Start correct processes to get in lock */
3712 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
3713 do {
3714 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003715 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3716 if (status < 0)
3717 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003718 /* Start FEC OC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003719 status = MPEGTSStart(state);
3720 if (status < 0)
3721 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003722 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003723 if (status < 0)
3724 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003725 } while (0);
3726 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003727}
3728
3729
3730/*============================================================================*/
3731
3732/**
3733* \brief Set up dvbt demodulator for channel.
3734* \param demod instance of demodulator.
3735* \return DRXStatus_t.
3736* // original DVBTSetChannel()
3737*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003738static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3739 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003740{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003741 u16 cmdResult = 0;
3742 u16 transmissionParams = 0;
3743 u16 operationMode = 0;
3744 u32 iqmRcRateOfs = 0;
3745 u32 bandwidth = 0;
3746 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003747 int status;
3748
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003749 dprintk(1, "\n");
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003750 /* printk(KERN_DEBUG "drxk: %s IF =%d, TFO = %d\n", __func__, IntermediateFreqkHz, tunerFreqOffset); */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003751 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003752 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3753 if (status < 0)
3754 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003755
3756 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003757 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003758 if (status < 0)
3759 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003760
3761 /* Stop processors */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003762 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003763 if (status < 0)
3764 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003765 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003766 if (status < 0)
3767 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003768
3769 /* Mandatory fix, always stop CP, required to set spl offset back to
3770 hardware default (is set to 0 by ucode during pilot detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003771 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003772 if (status < 0)
3773 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003774
3775 /*== Write channel settings to device =====================================*/
3776
3777 /* mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003778 switch (state->param.u.ofdm.transmission_mode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003779 case TRANSMISSION_MODE_AUTO:
3780 default:
3781 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3782 /* fall through , try first guess DRX_FFTMODE_8K */
3783 case TRANSMISSION_MODE_8K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003784 transmissionParams |=
3785 OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003786 break;
3787 case TRANSMISSION_MODE_2K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003788 transmissionParams |=
3789 OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003790 break;
3791 }
3792
3793 /* guard */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003794 switch (state->param.u.ofdm.guard_interval) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003795 default:
3796 case GUARD_INTERVAL_AUTO:
3797 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3798 /* fall through , try first guess DRX_GUARD_1DIV4 */
3799 case GUARD_INTERVAL_1_4:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003800 transmissionParams |=
3801 OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003802 break;
3803 case GUARD_INTERVAL_1_32:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003804 transmissionParams |=
3805 OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003806 break;
3807 case GUARD_INTERVAL_1_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003808 transmissionParams |=
3809 OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003810 break;
3811 case GUARD_INTERVAL_1_8:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003812 transmissionParams |=
3813 OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003814 break;
3815 }
3816
3817 /* hierarchy */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003818 switch (state->param.u.ofdm.hierarchy_information) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003819 case HIERARCHY_AUTO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003820 case HIERARCHY_NONE:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003821 default:
3822 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3823 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003824 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3825 /* break; */
3826 case HIERARCHY_1:
3827 transmissionParams |=
3828 OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003829 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003830 case HIERARCHY_2:
3831 transmissionParams |=
3832 OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003833 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003834 case HIERARCHY_4:
3835 transmissionParams |=
3836 OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003837 break;
3838 }
3839
3840
3841 /* constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003842 switch (state->param.u.ofdm.constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003843 case QAM_AUTO:
3844 default:
3845 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3846 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3847 case QAM_64:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003848 transmissionParams |=
3849 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003850 break;
3851 case QPSK:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003852 transmissionParams |=
3853 OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003854 break;
3855 case QAM_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003856 transmissionParams |=
3857 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003858 break;
3859 }
3860#if 0
Oliver Endrissebc7de22011-07-03 13:49:44 -03003861 /* No hierachical channels support in BDA */
3862 /* Priority (only for hierarchical channels) */
3863 switch (channel->priority) {
3864 case DRX_PRIORITY_LOW:
3865 transmissionParams |=
3866 OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3867 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3868 OFDM_EC_SB_PRIOR_LO);
3869 break;
3870 case DRX_PRIORITY_HIGH:
3871 transmissionParams |=
3872 OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3873 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3874 OFDM_EC_SB_PRIOR_HI));
3875 break;
3876 case DRX_PRIORITY_UNKNOWN: /* fall through */
3877 default:
3878 return DRX_STS_INVALID_ARG;
3879 break;
3880 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003881#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03003882 /* Set Priorty high */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003883 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003884 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003885 if (status < 0)
3886 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003887#endif
3888
3889 /* coderate */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003890 switch (state->param.u.ofdm.code_rate_HP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003891 case FEC_AUTO:
3892 default:
3893 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3894 /* fall through , try first guess DRX_CODERATE_2DIV3 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003895 case FEC_2_3:
3896 transmissionParams |=
3897 OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003898 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003899 case FEC_1_2:
3900 transmissionParams |=
3901 OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003902 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003903 case FEC_3_4:
3904 transmissionParams |=
3905 OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003906 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003907 case FEC_5_6:
3908 transmissionParams |=
3909 OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003910 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003911 case FEC_7_8:
3912 transmissionParams |=
3913 OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003914 break;
3915 }
3916
3917 /* SAW filter selection: normaly not necesarry, but if wanted
3918 the application can select a SAW filter via the driver by using UIOs */
3919 /* First determine real bandwidth (Hz) */
3920 /* Also set delay for impulse noise cruncher */
3921 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3922 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3923 functions */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003924 switch (state->param.u.ofdm.bandwidth) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003925 case BANDWIDTH_AUTO:
3926 case BANDWIDTH_8_MHZ:
3927 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003928 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003929 if (status < 0)
3930 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003931 /* cochannel protection for PAL 8 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003932 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003933 if (status < 0)
3934 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003935 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003936 if (status < 0)
3937 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003938 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003939 if (status < 0)
3940 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003941 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003942 if (status < 0)
3943 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003944 break;
3945 case BANDWIDTH_7_MHZ:
3946 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003947 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003948 if (status < 0)
3949 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003950 /* cochannel protection for PAL 7 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003951 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003952 if (status < 0)
3953 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003954 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003955 if (status < 0)
3956 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003957 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003958 if (status < 0)
3959 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003960 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003961 if (status < 0)
3962 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003963 break;
3964 case BANDWIDTH_6_MHZ:
3965 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003966 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003967 if (status < 0)
3968 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003969 /* cochannel protection for NTSC 6 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003970 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003971 if (status < 0)
3972 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003973 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003974 if (status < 0)
3975 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003976 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003977 if (status < 0)
3978 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003979 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003980 if (status < 0)
3981 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003982 break;
Mauro Carvalho Chehabe16cede2011-07-03 18:18:14 -03003983 default:
3984 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003985 }
3986
Oliver Endrissebc7de22011-07-03 13:49:44 -03003987 if (iqmRcRateOfs == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003988 /* Now compute IQM_RC_RATE_OFS
3989 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3990 =>
3991 ((SysFreq / BandWidth) * (2^21)) - (2^23)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003992 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003993 /* (SysFreq / BandWidth) * (2^28) */
3994 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
3995 => assert(MAX(sysClk) < 16*MIN(bandwidth))
3996 => assert(109714272 > 48000000) = true so Frac 28 can be used */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003997 iqmRcRateOfs = Frac28a((u32)
3998 ((state->m_sysClockFreq *
3999 1000) / 3), bandwidth);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004000 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4001 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004002 iqmRcRateOfs += 0x80L;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004003 iqmRcRateOfs = iqmRcRateOfs >> 7;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004004 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004005 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004006 }
4007
Oliver Endrissebc7de22011-07-03 13:49:44 -03004008 iqmRcRateOfs &=
4009 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4010 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004011 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004012 if (status < 0)
4013 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004014
4015 /* Bandwidth setting done */
4016
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004017#if 0
4018 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4019 if (status < 0)
4020 break;
4021#endif
4022 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4023 if (status < 0)
4024 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004025
4026 /*== Start SC, write channel settings to SC ===============================*/
4027
4028 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004029 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004030 if (status < 0)
4031 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004032
4033 /* Enable SC after setting all other parameters */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004034 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004035 if (status < 0)
4036 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004037 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004038 if (status < 0)
4039 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004040
4041
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004042 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4043 if (status < 0)
4044 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004045
4046 /* Write SC parameter registers, set all AUTO flags in operation mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004047 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4048 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4049 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4050 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4051 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4052 status =
4053 DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4054 0, transmissionParams, param1, 0, 0, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004055 if (!state->m_DRXK_A3_ROM_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004056 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4057 if (status < 0)
4058 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004059
Oliver Endrissebc7de22011-07-03 13:49:44 -03004060 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004061
4062 return status;
4063}
4064
4065
4066/*============================================================================*/
4067
4068/**
4069* \brief Retreive lock status .
4070* \param demod Pointer to demodulator instance.
4071* \param lockStat Pointer to lock status structure.
4072* \return DRXStatus_t.
4073*
4074*/
4075static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4076{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004077 int status;
4078 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4079 OFDM_SC_RA_RAM_LOCK_FEC__M);
4080 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4081 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004082
Oliver Endrissebc7de22011-07-03 13:49:44 -03004083 u16 ScRaRamLock = 0;
4084 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004085
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004086 dprintk(1, "\n");
4087
Oliver Endrissebc7de22011-07-03 13:49:44 -03004088 /* driver 0.9.0 */
4089 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004090 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004091 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP) {
4092 /* SC not active; return DRX_NOT_LOCKED */
4093 *pLockStatus = NOT_LOCKED;
4094 return status;
4095 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004096
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004097 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004098
Oliver Endrissebc7de22011-07-03 13:49:44 -03004099 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4100 *pLockStatus = MPEG_LOCK;
4101 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4102 *pLockStatus = FEC_LOCK;
4103 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4104 *pLockStatus = DEMOD_LOCK;
4105 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4106 *pLockStatus = NEVER_LOCK;
4107 else
4108 *pLockStatus = NOT_LOCKED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004109
Oliver Endrissebc7de22011-07-03 13:49:44 -03004110 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004111}
4112
Oliver Endrissebc7de22011-07-03 13:49:44 -03004113static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004114{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004115 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
4116 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004117
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004118 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004119 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004120 status = CtrlPowerMode(state, &powerMode);
4121 if (status < 0)
4122 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004123
Oliver Endrissebc7de22011-07-03 13:49:44 -03004124 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004125
Oliver Endrissebc7de22011-07-03 13:49:44 -03004126 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004127}
4128
4129
Oliver Endrissebc7de22011-07-03 13:49:44 -03004130/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004131static int PowerDownQAM(struct drxk_state *state)
4132{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004133 u16 data = 0;
4134 u16 cmdResult;
4135 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004136
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004137 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004138 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004139 status = read16(state, SCU_COMM_EXEC__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004140 if (status < 0)
4141 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004142 if (data == SCU_COMM_EXEC_ACTIVE) {
4143 /*
4144 STOP demodulator
4145 QAM and HW blocks
4146 */
4147 /* stop all comstate->m_exec */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004148 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004149 if (status < 0)
4150 break;
4151 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
4152 if (status < 0)
4153 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004154 }
4155 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004156 status = SetIqmAf(state, false);
4157 if (status < 0)
4158 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004159 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004160
Oliver Endrissebc7de22011-07-03 13:49:44 -03004161 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004162}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004163
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004164/*============================================================================*/
4165
4166/**
4167* \brief Setup of the QAM Measurement intervals for signal quality
4168* \param demod instance of demod.
4169* \param constellation current constellation.
4170* \return DRXStatus_t.
4171*
4172* NOTE:
4173* Take into account that for certain settings the errorcounters can overflow.
4174* The implementation does not check this.
4175*
4176*/
4177static int SetQAMMeasurement(struct drxk_state *state,
4178 enum EDrxkConstellation constellation,
4179 u32 symbolRate)
4180{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004181 u32 fecBitsDesired = 0; /* BER accounting period */
4182 u32 fecRsPeriodTotal = 0; /* Total period */
4183 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4184 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004185 int status = 0;
4186
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004187 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004188
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004189 fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004190 do {
4191
4192 /* fecBitsDesired = symbolRate [kHz] *
4193 FrameLenght [ms] *
4194 (constellation + 1) *
4195 SyncLoss (== 1) *
4196 ViterbiLoss (==1)
Oliver Endrissebc7de22011-07-03 13:49:44 -03004197 */
4198 switch (constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004199 case DRX_CONSTELLATION_QAM16:
4200 fecBitsDesired = 4 * symbolRate;
4201 break;
4202 case DRX_CONSTELLATION_QAM32:
4203 fecBitsDesired = 5 * symbolRate;
4204 break;
4205 case DRX_CONSTELLATION_QAM64:
4206 fecBitsDesired = 6 * symbolRate;
4207 break;
4208 case DRX_CONSTELLATION_QAM128:
4209 fecBitsDesired = 7 * symbolRate;
4210 break;
4211 case DRX_CONSTELLATION_QAM256:
4212 fecBitsDesired = 8 * symbolRate;
4213 break;
4214 default:
4215 status = -EINVAL;
4216 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004217 status = status;
4218 if (status < 0)
4219 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004220
Oliver Endrissebc7de22011-07-03 13:49:44 -03004221 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4222 fecBitsDesired *= 500; /* meas. period [ms] */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004223
4224 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4225 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004226 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004227
4228 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4229 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4230 if (fecRsPrescale == 0) {
4231 /* Divide by zero (though impossible) */
4232 status = -1;
4233 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004234 status = status;
4235 if (status < 0)
4236 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004237 fecRsPeriod =
4238 ((u16) fecRsPeriodTotal +
4239 (fecRsPrescale >> 1)) / fecRsPrescale;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004240
4241 /* write corresponding registers */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004242 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004243 if (status < 0)
4244 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004245 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004246 if (status < 0)
4247 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004248 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004249 if (status < 0)
4250 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004251
4252 } while (0);
4253
Oliver Endrissebc7de22011-07-03 13:49:44 -03004254 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03004255 printk(KERN_ERR "drxk: %s: status - %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004256
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004257 return status;
4258}
4259
Oliver Endrissebc7de22011-07-03 13:49:44 -03004260static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004261{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004262 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004263
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004264 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004265 do {
4266 /* QAM Equalizer Setup */
4267 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004268 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004269 if (status < 0)
4270 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004271 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004272 if (status < 0)
4273 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004274 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004275 if (status < 0)
4276 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004277 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004278 if (status < 0)
4279 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004280 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004281 if (status < 0)
4282 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004283 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004284 if (status < 0)
4285 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004286 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004287 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004288 if (status < 0)
4289 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004290 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004291 if (status < 0)
4292 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004293 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004294 if (status < 0)
4295 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004296 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004297 if (status < 0)
4298 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004299 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004300 if (status < 0)
4301 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004302 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004303 if (status < 0)
4304 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004305
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004306 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004307 if (status < 0)
4308 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004309 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004310 if (status < 0)
4311 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004312 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004313 if (status < 0)
4314 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004315
Oliver Endrissebc7de22011-07-03 13:49:44 -03004316 /* QAM Slicer Settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004317 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004318 if (status < 0)
4319 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004320
Oliver Endrissebc7de22011-07-03 13:49:44 -03004321 /* QAM Loop Controller Coeficients */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004322 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004323 if (status < 0)
4324 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004325 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004326 if (status < 0)
4327 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004328 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004329 if (status < 0)
4330 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004331 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004332 if (status < 0)
4333 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004334 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004335 if (status < 0)
4336 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004337 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004338 if (status < 0)
4339 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004340 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004341 if (status < 0)
4342 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004343 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004344 if (status < 0)
4345 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004346
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004347 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004348 if (status < 0)
4349 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004350 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004351 if (status < 0)
4352 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004353 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004354 if (status < 0)
4355 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004356 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004357 if (status < 0)
4358 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004359 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004360 if (status < 0)
4361 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004362 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004363 if (status < 0)
4364 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004365 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004366 if (status < 0)
4367 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004368 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004369 if (status < 0)
4370 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004371 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004372 if (status < 0)
4373 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004374 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004375 if (status < 0)
4376 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004377 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004378 if (status < 0)
4379 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004380 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004381 if (status < 0)
4382 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004383
4384
Oliver Endrissebc7de22011-07-03 13:49:44 -03004385 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004386
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004387 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004388 if (status < 0)
4389 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004390 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004391 if (status < 0)
4392 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004393 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004394 if (status < 0)
4395 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004396 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004397 if (status < 0)
4398 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004399 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004400 if (status < 0)
4401 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004402 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004403 if (status < 0)
4404 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004405
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004406 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004407 if (status < 0)
4408 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004409 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004410 if (status < 0)
4411 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004412 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004413 if (status < 0)
4414 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004415
4416
Oliver Endrissebc7de22011-07-03 13:49:44 -03004417 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004418
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004419 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004420 if (status < 0)
4421 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004422 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004423 if (status < 0)
4424 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004425 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004426 if (status < 0)
4427 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004428 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004429 if (status < 0)
4430 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004431 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004432 if (status < 0)
4433 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004434 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004435 if (status < 0)
4436 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004437 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004438 if (status < 0)
4439 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004440 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004441
Oliver Endrissebc7de22011-07-03 13:49:44 -03004442 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004443}
4444
4445/*============================================================================*/
4446
4447/**
4448* \brief QAM32 specific setup
4449* \param demod instance of demod.
4450* \return DRXStatus_t.
4451*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004452static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004453{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004454 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004455
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004456 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004457 do {
4458 /* QAM Equalizer Setup */
4459 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004460 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004461 if (status < 0)
4462 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004463 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004464 if (status < 0)
4465 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004466 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004467 if (status < 0)
4468 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004469 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
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, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
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, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004476 if (status < 0)
4477 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004478
Oliver Endrissebc7de22011-07-03 13:49:44 -03004479 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004480 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004481 if (status < 0)
4482 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004483 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004484 if (status < 0)
4485 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004486 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004487 if (status < 0)
4488 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004489 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004490 if (status < 0)
4491 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004492 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004493 if (status < 0)
4494 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004495 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004496 if (status < 0)
4497 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004498
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004499 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004500 if (status < 0)
4501 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004502 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004503 if (status < 0)
4504 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004505 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004506 if (status < 0)
4507 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004508
Oliver Endrissebc7de22011-07-03 13:49:44 -03004509 /* QAM Slicer Settings */
4510
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004511 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004512 if (status < 0)
4513 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004514
4515
Oliver Endrissebc7de22011-07-03 13:49:44 -03004516 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004517
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004518 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004519 if (status < 0)
4520 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004521 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004522 if (status < 0)
4523 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004524 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004525 if (status < 0)
4526 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004527 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004528 if (status < 0)
4529 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004530 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004531 if (status < 0)
4532 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004533 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004534 if (status < 0)
4535 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004536 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004537 if (status < 0)
4538 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004539 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004540 if (status < 0)
4541 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004542
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004543 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004544 if (status < 0)
4545 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004546 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004547 if (status < 0)
4548 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004549 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004550 if (status < 0)
4551 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004552 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004553 if (status < 0)
4554 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004555 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004556 if (status < 0)
4557 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004558 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004559 if (status < 0)
4560 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004561 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004562 if (status < 0)
4563 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004564 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004565 if (status < 0)
4566 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004567 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004568 if (status < 0)
4569 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004570 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004571 if (status < 0)
4572 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004573 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004574 if (status < 0)
4575 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004576 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004577 if (status < 0)
4578 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004579
4580
Oliver Endrissebc7de22011-07-03 13:49:44 -03004581 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004582
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004583 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004584 if (status < 0)
4585 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004586 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004587 if (status < 0)
4588 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004589 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004590 if (status < 0)
4591 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004592 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004593 if (status < 0)
4594 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004595 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004596 if (status < 0)
4597 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004598 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004599 if (status < 0)
4600 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004601
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004602 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004603 if (status < 0)
4604 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004605 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004606 if (status < 0)
4607 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004608 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004609 if (status < 0)
4610 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004611
4612
Oliver Endrissebc7de22011-07-03 13:49:44 -03004613 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004614
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004615 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004616 if (status < 0)
4617 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004618 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004619 if (status < 0)
4620 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004621 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004622 if (status < 0)
4623 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004624 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004625 if (status < 0)
4626 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004627 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004628 if (status < 0)
4629 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004630 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004631 if (status < 0)
4632 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004633 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004634 if (status < 0)
4635 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004636 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004637
Oliver Endrissebc7de22011-07-03 13:49:44 -03004638 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004639}
4640
4641/*============================================================================*/
4642
4643/**
4644* \brief QAM64 specific setup
4645* \param demod instance of demod.
4646* \return DRXStatus_t.
4647*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004648static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004649{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004650 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004651
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004652 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004653 do {
4654 /* QAM Equalizer Setup */
4655 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004656 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004657 if (status < 0)
4658 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004659 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004660 if (status < 0)
4661 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004662 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004663 if (status < 0)
4664 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004665 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
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, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
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, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004672 if (status < 0)
4673 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004674
Oliver Endrissebc7de22011-07-03 13:49:44 -03004675 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004676 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004677 if (status < 0)
4678 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004679 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004680 if (status < 0)
4681 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004682 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004683 if (status < 0)
4684 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004685 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004686 if (status < 0)
4687 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004688 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004689 if (status < 0)
4690 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004691 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004692 if (status < 0)
4693 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004694
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004695 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004696 if (status < 0)
4697 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004698 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004699 if (status < 0)
4700 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004701 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004702 if (status < 0)
4703 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004704
4705 /* QAM Slicer Settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004706 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004707 if (status < 0)
4708 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004709
4710
Oliver Endrissebc7de22011-07-03 13:49:44 -03004711 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004712
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004713 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004714 if (status < 0)
4715 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004716 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004717 if (status < 0)
4718 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004719 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004720 if (status < 0)
4721 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004722 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004723 if (status < 0)
4724 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004725 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004726 if (status < 0)
4727 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004728 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004729 if (status < 0)
4730 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004731 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004732 if (status < 0)
4733 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004734 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004735 if (status < 0)
4736 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004737
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004738 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004739 if (status < 0)
4740 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004741 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004742 if (status < 0)
4743 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004744 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004745 if (status < 0)
4746 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004747 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004748 if (status < 0)
4749 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004750 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004751 if (status < 0)
4752 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004753 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004754 if (status < 0)
4755 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004756 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004757 if (status < 0)
4758 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004759 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004760 if (status < 0)
4761 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004762 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004763 if (status < 0)
4764 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004765 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004766 if (status < 0)
4767 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004768 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004769 if (status < 0)
4770 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004771 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004772 if (status < 0)
4773 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004774
4775
Oliver Endrissebc7de22011-07-03 13:49:44 -03004776 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004777
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004778 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004779 if (status < 0)
4780 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004781 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004782 if (status < 0)
4783 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004784 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004785 if (status < 0)
4786 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004787 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004788 if (status < 0)
4789 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004790 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004791 if (status < 0)
4792 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004793 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004794 if (status < 0)
4795 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004796
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004797 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004798 if (status < 0)
4799 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004800 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004801 if (status < 0)
4802 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004803 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004804 if (status < 0)
4805 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004806
4807
Oliver Endrissebc7de22011-07-03 13:49:44 -03004808 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004809
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004810 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004811 if (status < 0)
4812 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004813 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004814 if (status < 0)
4815 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004816 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004817 if (status < 0)
4818 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004819 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004820 if (status < 0)
4821 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004822 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004823 if (status < 0)
4824 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004825 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004826 if (status < 0)
4827 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004828 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004829 if (status < 0)
4830 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004831 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004832
Oliver Endrissebc7de22011-07-03 13:49:44 -03004833 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004834}
4835
4836/*============================================================================*/
4837
4838/**
4839* \brief QAM128 specific setup
4840* \param demod: instance of demod.
4841* \return DRXStatus_t.
4842*/
4843static int SetQAM128(struct drxk_state *state)
4844{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004845 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004846
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004847 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004848 do {
4849 /* QAM Equalizer Setup */
4850 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004851 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004852 if (status < 0)
4853 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004854 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004855 if (status < 0)
4856 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004857 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004858 if (status < 0)
4859 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004860 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
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, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
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, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004867 if (status < 0)
4868 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004869
Oliver Endrissebc7de22011-07-03 13:49:44 -03004870 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004871 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004872 if (status < 0)
4873 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004874 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004875 if (status < 0)
4876 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004877 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004878 if (status < 0)
4879 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004880 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004881 if (status < 0)
4882 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004883 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004884 if (status < 0)
4885 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004886 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004887 if (status < 0)
4888 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004889
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004890 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004891 if (status < 0)
4892 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004893 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004894 if (status < 0)
4895 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004896 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004897 if (status < 0)
4898 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004899
4900
Oliver Endrissebc7de22011-07-03 13:49:44 -03004901 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004902
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004903 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004904 if (status < 0)
4905 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004906
4907
Oliver Endrissebc7de22011-07-03 13:49:44 -03004908 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004909
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004910 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004911 if (status < 0)
4912 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004913 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004914 if (status < 0)
4915 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004916 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004917 if (status < 0)
4918 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004919 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004920 if (status < 0)
4921 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004922 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004923 if (status < 0)
4924 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004925 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004926 if (status < 0)
4927 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004928 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004929 if (status < 0)
4930 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004931 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004932 if (status < 0)
4933 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004934
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004935 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004936 if (status < 0)
4937 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004938 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004939 if (status < 0)
4940 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004941 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004942 if (status < 0)
4943 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004944 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004945 if (status < 0)
4946 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004947 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004948 if (status < 0)
4949 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004950 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004951 if (status < 0)
4952 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004953 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004954 if (status < 0)
4955 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004956 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004957 if (status < 0)
4958 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004959 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004960 if (status < 0)
4961 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004962 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004963 if (status < 0)
4964 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004965 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004966 if (status < 0)
4967 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004968 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004969 if (status < 0)
4970 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004971
4972
Oliver Endrissebc7de22011-07-03 13:49:44 -03004973 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004974
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004975 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004976 if (status < 0)
4977 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004978 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004979 if (status < 0)
4980 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004981 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004982 if (status < 0)
4983 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004984 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004985 if (status < 0)
4986 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004987 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004988 if (status < 0)
4989 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004990 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004991 if (status < 0)
4992 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004993
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004994 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004995 if (status < 0)
4996 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004997 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004998 if (status < 0)
4999 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005000
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005001 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005002 if (status < 0)
5003 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005004
Oliver Endrissebc7de22011-07-03 13:49:44 -03005005 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005006
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005007 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005008 if (status < 0)
5009 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005010 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005011 if (status < 0)
5012 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005013 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005014 if (status < 0)
5015 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005016 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005017 if (status < 0)
5018 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005019 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005020 if (status < 0)
5021 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005022 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005023 if (status < 0)
5024 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005025 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005026 if (status < 0)
5027 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005028 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005029
Oliver Endrissebc7de22011-07-03 13:49:44 -03005030 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005031}
5032
5033/*============================================================================*/
5034
5035/**
5036* \brief QAM256 specific setup
5037* \param demod: instance of demod.
5038* \return DRXStatus_t.
5039*/
5040static int SetQAM256(struct drxk_state *state)
5041{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005042 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005043
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005044 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005045 do {
5046 /* QAM Equalizer Setup */
5047 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005048 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005049 if (status < 0)
5050 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005051 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005052 if (status < 0)
5053 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005054 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005055 if (status < 0)
5056 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005057 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
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, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
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, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005064 if (status < 0)
5065 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005066
Oliver Endrissebc7de22011-07-03 13:49:44 -03005067 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005068 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005069 if (status < 0)
5070 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005071 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005072 if (status < 0)
5073 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005074 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005075 if (status < 0)
5076 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005077 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005078 if (status < 0)
5079 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005080 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005081 if (status < 0)
5082 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005083 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005084 if (status < 0)
5085 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005086
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005087 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005088 if (status < 0)
5089 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005090 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005091 if (status < 0)
5092 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005093 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005094 if (status < 0)
5095 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005096
Oliver Endrissebc7de22011-07-03 13:49:44 -03005097 /* QAM Slicer Settings */
5098
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005099 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005100 if (status < 0)
5101 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005102
5103
Oliver Endrissebc7de22011-07-03 13:49:44 -03005104 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005105
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005106 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005107 if (status < 0)
5108 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005109 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005110 if (status < 0)
5111 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005112 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005113 if (status < 0)
5114 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005115 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005116 if (status < 0)
5117 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005118 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005119 if (status < 0)
5120 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005121 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005122 if (status < 0)
5123 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005124 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005125 if (status < 0)
5126 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005127 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005128 if (status < 0)
5129 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005130
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005131 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005132 if (status < 0)
5133 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005134 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005135 if (status < 0)
5136 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005137 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005138 if (status < 0)
5139 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005140 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005141 if (status < 0)
5142 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005143 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005144 if (status < 0)
5145 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005146 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005147 if (status < 0)
5148 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005149 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005150 if (status < 0)
5151 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005152 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005153 if (status < 0)
5154 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005155 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005156 if (status < 0)
5157 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005158 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005159 if (status < 0)
5160 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005161 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005162 if (status < 0)
5163 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005164 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005165 if (status < 0)
5166 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005167
5168
Oliver Endrissebc7de22011-07-03 13:49:44 -03005169 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005170
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005171 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005172 if (status < 0)
5173 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005174 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005175 if (status < 0)
5176 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005177 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005178 if (status < 0)
5179 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005180 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005181 if (status < 0)
5182 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005183 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005184 if (status < 0)
5185 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005186 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005187 if (status < 0)
5188 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005189
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005190 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005191 if (status < 0)
5192 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005193 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005194 if (status < 0)
5195 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005196 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005197 if (status < 0)
5198 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005199
5200
Oliver Endrissebc7de22011-07-03 13:49:44 -03005201 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005202
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005203 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005204 if (status < 0)
5205 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005206 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005207 if (status < 0)
5208 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005209 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005210 if (status < 0)
5211 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005212 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005213 if (status < 0)
5214 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005215 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005216 if (status < 0)
5217 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005218 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005219 if (status < 0)
5220 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005221 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005222 if (status < 0)
5223 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005224 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005225
Oliver Endrissebc7de22011-07-03 13:49:44 -03005226 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005227}
5228
5229
5230/*============================================================================*/
5231/**
5232* \brief Reset QAM block.
5233* \param demod: instance of demod.
5234* \param channel: pointer to channel data.
5235* \return DRXStatus_t.
5236*/
5237static int QAMResetQAM(struct drxk_state *state)
5238{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005239 int status;
5240 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005241
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005242 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005243 do {
5244 /* Stop QAM comstate->m_exec */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005245 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005246 if (status < 0)
5247 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005248
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005249 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5250 if (status < 0)
5251 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005252 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005253
Oliver Endrissebc7de22011-07-03 13:49:44 -03005254 /* All done, all OK */
5255 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005256}
5257
5258/*============================================================================*/
5259
5260/**
5261* \brief Set QAM symbolrate.
5262* \param demod: instance of demod.
5263* \param channel: pointer to channel data.
5264* \return DRXStatus_t.
5265*/
5266static int QAMSetSymbolrate(struct drxk_state *state)
5267{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005268 u32 adcFrequency = 0;
5269 u32 symbFreq = 0;
5270 u32 iqmRcRate = 0;
5271 u16 ratesel = 0;
5272 u32 lcSymbRate = 0;
5273 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005274
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005275 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005276 do {
5277 /* Select & calculate correct IQM rate */
5278 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5279 ratesel = 0;
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005280 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005281 if (state->param.u.qam.symbol_rate <= 1188750)
5282 ratesel = 3;
5283 else if (state->param.u.qam.symbol_rate <= 2377500)
5284 ratesel = 2;
5285 else if (state->param.u.qam.symbol_rate <= 4755000)
5286 ratesel = 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005287 status = write16(state, IQM_FD_RATESEL__A, ratesel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005288 if (status < 0)
5289 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005290
Oliver Endrissebc7de22011-07-03 13:49:44 -03005291 /*
5292 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5293 */
5294 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5295 if (symbFreq == 0) {
5296 /* Divide by zero */
5297 return -1;
5298 }
5299 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5300 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5301 (1 << 23);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005302 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005303 if (status < 0)
5304 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005305 state->m_iqmRcRate = iqmRcRate;
5306 /*
5307 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5308 */
5309 symbFreq = state->param.u.qam.symbol_rate;
5310 if (adcFrequency == 0) {
5311 /* Divide by zero */
5312 return -1;
5313 }
5314 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5315 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5316 16);
5317 if (lcSymbRate > 511)
5318 lcSymbRate = 511;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005319 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005320 if (status < 0)
5321 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005322 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005323
Oliver Endrissebc7de22011-07-03 13:49:44 -03005324 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005325}
5326
5327/*============================================================================*/
5328
5329/**
5330* \brief Get QAM lock status.
5331* \param demod: instance of demod.
5332* \param channel: pointer to channel data.
5333* \return DRXStatus_t.
5334*/
5335
5336static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5337{
5338 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005339 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005340
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005341 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005342 status =
5343 scu_command(state,
5344 SCU_RAM_COMMAND_STANDARD_QAM |
5345 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5346 Result);
5347 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005348 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005349
5350 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005351 /* 0x0000 NOT LOCKED */
5352 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005353 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005354 /* 0x4000 DEMOD LOCKED */
5355 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005356 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005357 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5358 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005359 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005360 /* 0xC000 NEVER LOCKED */
5361 /* (system will never be able to lock to the signal) */
5362 /* TODO: check this, intermediate & standard specific lock states are not
5363 taken into account here */
5364 *pLockStatus = NEVER_LOCK;
5365 }
5366 return status;
5367}
5368
5369#define QAM_MIRROR__M 0x03
5370#define QAM_MIRROR_NORMAL 0x00
5371#define QAM_MIRRORED 0x01
5372#define QAM_MIRROR_AUTO_ON 0x02
5373#define QAM_LOCKRANGE__M 0x10
5374#define QAM_LOCKRANGE_NORMAL 0x10
5375
Oliver Endrissebc7de22011-07-03 13:49:44 -03005376static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5377 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005378{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005379 int status = 0;
5380 u8 parameterLen;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005381 u16 setEnvParameters[5];
5382 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5383 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005384
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005385 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005386 do {
5387 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005388 STEP 1: reset demodulator
5389 resets FEC DI and FEC RS
5390 resets QAM block
5391 resets SCU variables
5392 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005393 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005394 if (status < 0)
5395 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005396 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005397 if (status < 0)
5398 break;
5399 status = QAMResetQAM(state);
5400 if (status < 0)
5401 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005402
5403 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005404 STEP 2: configure demodulator
5405 -set env
5406 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5407 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005408 status = QAMSetSymbolrate(state);
5409 if (status < 0)
5410 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005411
5412 /* Env parameters */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005413 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005414 if (state->m_OperationMode == OM_QAM_ITU_C)
Oliver Endrissebc7de22011-07-03 13:49:44 -03005415 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005416 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005417 /* check for LOCKRANGE Extented */
5418 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005419 parameterLen = 4;
5420
5421 /* Set params */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005422 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005423 case QAM_256:
5424 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5425 break;
5426 case QAM_AUTO:
5427 case QAM_64:
5428 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5429 break;
5430 case QAM_16:
5431 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5432 break;
5433 case QAM_32:
5434 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5435 break;
5436 case QAM_128:
5437 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5438 break;
5439 default:
5440 status = -EINVAL;
5441 break;
5442 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005443 status = status;
5444 if (status < 0)
5445 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005446 setParamParameters[0] = state->m_Constellation; /* constellation */
5447 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005448
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005449 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5450 if (status < 0)
5451 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005452
5453
5454 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5455 setup constellation independent registers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005456#if 0
5457 status = SetFrequency (channel, tunerFreqOffset));
5458 if (status < 0)
5459 break;
5460#endif
5461 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5462 if (status < 0)
5463 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005464
5465 /* Setup BER measurement */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005466 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5467 if (status < 0)
5468 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005469
5470 /* Reset default values */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005471 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
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_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005475 if (status < 0)
5476 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005477
Oliver Endrissebc7de22011-07-03 13:49:44 -03005478 /* Reset default LC values */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005479 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005480 if (status < 0)
5481 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005482 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005483 if (status < 0)
5484 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005485 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005486 if (status < 0)
5487 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005488 status = write16(state, QAM_LC_MODE__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005489 if (status < 0)
5490 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005491
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005492 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005493 if (status < 0)
5494 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005495 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005496 if (status < 0)
5497 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005498 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005499 if (status < 0)
5500 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005501 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005502 if (status < 0)
5503 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005504 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005505 if (status < 0)
5506 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005507 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005508 if (status < 0)
5509 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005510 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005511 if (status < 0)
5512 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005513 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005514 if (status < 0)
5515 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005516 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005517 if (status < 0)
5518 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005519 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005520 if (status < 0)
5521 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005522 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005523 if (status < 0)
5524 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005525 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005526 if (status < 0)
5527 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005528 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005529 if (status < 0)
5530 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005531 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005532 if (status < 0)
5533 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005534 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005535 if (status < 0)
5536 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005537
Oliver Endrissebc7de22011-07-03 13:49:44 -03005538 /* Mirroring, QAM-block starting point not inverted */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005539 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005540 if (status < 0)
5541 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005542
Oliver Endrissebc7de22011-07-03 13:49:44 -03005543 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005544 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005545 if (status < 0)
5546 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005547
Oliver Endrissebc7de22011-07-03 13:49:44 -03005548 /* STEP 4: constellation specific setup */
5549 switch (state->param.u.qam.modulation) {
5550 case QAM_16:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005551 status = SetQAM16(state);
5552 if (status < 0)
5553 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005554 break;
5555 case QAM_32:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005556 status = SetQAM32(state);
5557 if (status < 0)
5558 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005559 break;
5560 case QAM_AUTO:
5561 case QAM_64:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005562 status = SetQAM64(state);
5563 if (status < 0)
5564 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005565 break;
5566 case QAM_128:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005567 status = SetQAM128(state);
5568 if (status < 0)
5569 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005570 break;
5571 case QAM_256:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005572 status = SetQAM256(state);
5573 if (status < 0)
5574 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005575 break;
5576 default:
5577 return -1;
5578 break;
5579 } /* switch */
5580 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005581 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005582 if (status < 0)
5583 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005584
5585
Oliver Endrissebc7de22011-07-03 13:49:44 -03005586 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5587 /* extAttr->currentChannel.constellation = channel->constellation; */
5588 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005589 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5590 if (status < 0)
5591 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005592
Oliver Endrissebc7de22011-07-03 13:49:44 -03005593 /* Start processes */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005594 status = MPEGTSStart(state);
5595 if (status < 0)
5596 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005597 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005598 if (status < 0)
5599 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005600 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005601 if (status < 0)
5602 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005603 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005604 if (status < 0)
5605 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005606
Oliver Endrissebc7de22011-07-03 13:49:44 -03005607 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005608 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5609 if (status < 0)
5610 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005611
Oliver Endrissebc7de22011-07-03 13:49:44 -03005612 /* update global DRXK data container */
5613 /*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005614
Oliver Endrissebc7de22011-07-03 13:49:44 -03005615 /* All done, all OK */
5616 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005617
Oliver Endrissebc7de22011-07-03 13:49:44 -03005618 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005619 printk(KERN_ERR "drxk: %s %d\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005620
5621 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005622}
5623
Oliver Endrissebc7de22011-07-03 13:49:44 -03005624static int SetQAMStandard(struct drxk_state *state,
5625 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005626{
5627#ifdef DRXK_QAM_TAPS
5628#define DRXK_QAMA_TAPS_SELECT
5629#include "drxk_filters.h"
5630#undef DRXK_QAMA_TAPS_SELECT
5631#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03005632 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005633#endif
5634
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005635 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005636 do {
5637 /* added antenna switch */
5638 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005639
Oliver Endrissebc7de22011-07-03 13:49:44 -03005640 /* Ensure correct power-up mode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005641 status = PowerUpQAM(state);
5642 if (status < 0)
5643 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005644 /* Reset QAM block */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005645 status = QAMResetQAM(state);
5646 if (status < 0)
5647 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005648
Oliver Endrissebc7de22011-07-03 13:49:44 -03005649 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005650
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005651 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005652 if (status < 0)
5653 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005654 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005655 if (status < 0)
5656 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005657
Oliver Endrissebc7de22011-07-03 13:49:44 -03005658 /* Upload IQM Channel Filter settings by
5659 boot loader from ROM table */
5660 switch (oMode) {
5661 case OM_QAM_ITU_A:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005662 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5663 if (status < 0)
5664 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005665 break;
5666 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005667 status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5668 if (status < 0)
5669 break;
5670 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5671 if (status < 0)
5672 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005673 break;
5674 default:
5675 status = -EINVAL;
5676 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005677 status = status;
5678 if (status < 0)
5679 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005680
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005681 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005682 if (status < 0)
5683 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005684 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005685 if (status < 0)
5686 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005687 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 -03005688 if (status < 0)
5689 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005690
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005691 status = write16(state, IQM_RC_STRETCH__A, 21);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005692 if (status < 0)
5693 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005694 status = write16(state, IQM_AF_CLP_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005695 if (status < 0)
5696 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005697 status = write16(state, IQM_AF_CLP_TH__A, 448);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005698 if (status < 0)
5699 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005700 status = write16(state, IQM_AF_SNS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005701 if (status < 0)
5702 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005703 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005704 if (status < 0)
5705 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005706
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005707 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005708 if (status < 0)
5709 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005710 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
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_ADJ_SEL__A, 1);
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_AF_UPD_SEL__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005717 if (status < 0)
5718 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005719
Oliver Endrissebc7de22011-07-03 13:49:44 -03005720 /* IQM Impulse Noise Processing Unit */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005721 status = write16(state, IQM_CF_CLP_VAL__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005722 if (status < 0)
5723 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005724 status = write16(state, IQM_CF_DATATH__A, 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005725 if (status < 0)
5726 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005727 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005728 if (status < 0)
5729 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005730 status = write16(state, IQM_CF_DET_LCT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005731 if (status < 0)
5732 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005733 status = write16(state, IQM_CF_WND_LEN__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005734 if (status < 0)
5735 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005736 status = write16(state, IQM_CF_PKDTH__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005737 if (status < 0)
5738 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005739 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005740 if (status < 0)
5741 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005742
Oliver Endrissebc7de22011-07-03 13:49:44 -03005743 /* turn on IQMAF. Must be done before setAgc**() */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005744 status = SetIqmAf(state, true);
5745 if (status < 0)
5746 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005747 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005748 if (status < 0)
5749 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005750
Oliver Endrissebc7de22011-07-03 13:49:44 -03005751 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005752 status = ADCSynchronization(state);
5753 if (status < 0)
5754 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005755
Oliver Endrissebc7de22011-07-03 13:49:44 -03005756 /* Set the FSM step period */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005757 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005758 if (status < 0)
5759 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005760
Oliver Endrissebc7de22011-07-03 13:49:44 -03005761 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005762 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005763 if (status < 0)
5764 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005765
Oliver Endrissebc7de22011-07-03 13:49:44 -03005766 /* No more resets of the IQM, current standard correctly set =>
5767 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005768
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005769 status = InitAGC(state, true);
5770 if (status < 0)
5771 break;
5772 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5773 if (status < 0)
5774 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005775
Oliver Endrissebc7de22011-07-03 13:49:44 -03005776 /* Configure AGC's */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005777 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5778 if (status < 0)
5779 break;
5780 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5781 if (status < 0)
5782 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005783
Oliver Endrissebc7de22011-07-03 13:49:44 -03005784 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005785 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005786 if (status < 0)
5787 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005788 } while (0);
5789 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005790}
5791
5792static int WriteGPIO(struct drxk_state *state)
5793{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005794 int status;
5795 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005796
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005797 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005798 do {
5799 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005800 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
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 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005805 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005806 if (status < 0)
5807 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005808
Oliver Endrissebc7de22011-07-03 13:49:44 -03005809 if (state->m_hasSAWSW) {
5810 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005811 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005812 if (status < 0)
5813 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005814
Oliver Endrissebc7de22011-07-03 13:49:44 -03005815 /* use corresponding bit in io data output registar */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005816 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005817 if (status < 0)
5818 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005819 if (state->m_GPIO == 0)
5820 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5821 else
5822 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5823 /* write back to io data output register */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005824 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005825 if (status < 0)
5826 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005827
Oliver Endrissebc7de22011-07-03 13:49:44 -03005828 }
5829 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005830 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005831 if (status < 0)
5832 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005833 } while (0);
5834 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005835}
5836
5837static int SwitchAntennaToQAM(struct drxk_state *state)
5838{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005839 int status = -1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005840
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005841 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005842 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5843 if (state->m_GPIO != state->m_AntennaDVBC) {
5844 state->m_GPIO = state->m_AntennaDVBC;
5845 status = WriteGPIO(state);
5846 }
5847 }
5848 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005849}
5850
5851static int SwitchAntennaToDVBT(struct drxk_state *state)
5852{
5853 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005854
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005855 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005856 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5857 if (state->m_GPIO != state->m_AntennaDVBT) {
5858 state->m_GPIO = state->m_AntennaDVBT;
5859 status = WriteGPIO(state);
5860 }
5861 }
5862 return status;
5863}
5864
5865
5866static int PowerDownDevice(struct drxk_state *state)
5867{
5868 /* Power down to requested mode */
5869 /* Backup some register settings */
5870 /* Set pins with possible pull-ups connected to them in input mode */
5871 /* Analog power down */
5872 /* ADC power down */
5873 /* Power down device */
5874 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005875
5876 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005877 do {
5878 if (state->m_bPDownOpenBridge) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03005879 /* Open I2C bridge before power down of DRXK */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005880 status = ConfigureI2CBridge(state, true);
5881 if (status < 0)
5882 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005883 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005884 /* driver 0.9.0 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005885 status = DVBTEnableOFDMTokenRing(state, false);
5886 if (status < 0)
5887 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005888
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005889 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005890 if (status < 0)
5891 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005892 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005893 if (status < 0)
5894 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005895 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005896 status = HI_CfgCommand(state);
5897 if (status < 0)
5898 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005899 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005900
Oliver Endrissebc7de22011-07-03 13:49:44 -03005901 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005902 return -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005903
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005904 return 0;
5905}
5906
5907static int load_microcode(struct drxk_state *state, char *mc_name)
5908{
5909 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005910 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005911
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005912 dprintk(1, "\n");
5913
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005914 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5915 if (err < 0) {
5916 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005917 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005918 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005919 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005920 return err;
5921 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005922 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005923 release_firmware(fw);
5924 return err;
5925}
5926
5927static int init_drxk(struct drxk_state *state)
5928{
5929 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005930 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005931 u16 driverVersion;
5932
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005933 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005934 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
5935 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005936 status = PowerUpDevice(state);
5937 if (status < 0)
5938 break;
5939 status = DRXX_Open(state);
5940 if (status < 0)
5941 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005942 /* Soft reset of OFDM-, sys- and osc-clockdomain */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005943 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 -03005944 if (status < 0)
5945 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005946 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005947 if (status < 0)
5948 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005949 /* TODO is this needed, if yes how much delay in worst case scenario */
5950 msleep(1);
5951 state->m_DRXK_A3_PATCH_CODE = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005952 status = GetDeviceCapabilities(state);
5953 if (status < 0)
5954 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005955
5956 /* Bridge delay, uses oscilator clock */
5957 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5958 /* SDA brdige delay */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005959 state->m_HICfgBridgeDelay =
5960 (u16) ((state->m_oscClockFreq / 1000) *
5961 HI_I2C_BRIDGE_DELAY) / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005962 /* Clipping */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005963 if (state->m_HICfgBridgeDelay >
5964 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
5965 state->m_HICfgBridgeDelay =
5966 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005967 }
5968 /* SCL bridge delay, same as SDA for now */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005969 state->m_HICfgBridgeDelay +=
5970 state->m_HICfgBridgeDelay <<
5971 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005972
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005973 status = InitHI(state);
5974 if (status < 0)
5975 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005976 /* disable various processes */
5977#if NOA1ROM
Oliver Endrissebc7de22011-07-03 13:49:44 -03005978 if (!(state->m_DRXK_A1_ROM_CODE)
5979 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005980#endif
5981 {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005982 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005983 if (status < 0)
5984 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005985 }
5986
5987 /* disable MPEG port */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005988 status = MPEGTSDisable(state);
5989 if (status < 0)
5990 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005991
5992 /* Stop AUD and SCU */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005993 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005994 if (status < 0)
5995 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005996 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005997 if (status < 0)
5998 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005999
6000 /* enable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006001 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 -03006002 if (status < 0)
6003 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006004
6005 /* include boot loader section */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006006 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006007 if (status < 0)
6008 break;
6009 status = BLChainCmd(state, 0, 6, 100);
6010 if (status < 0)
6011 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006012
6013#if 0
6014 if (state->m_DRXK_A3_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006015 status = DownloadMicrocode(state, DRXK_A3_microcode, DRXK_A3_microcode_length);
6016 if (status < 0)
6017 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006018#else
6019 load_microcode(state, "drxk_a3.mc");
6020#endif
6021#if NOA1ROM
6022 if (state->m_DRXK_A2_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006023 status = DownloadMicrocode(state, DRXK_A2_microcode, DRXK_A2_microcode_length);
6024 if (status < 0)
6025 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006026#endif
6027 /* disable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006028 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 -03006029 if (status < 0)
6030 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006031
6032 /* Run SCU for a little while to initialize microcode version numbers */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006033 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006034 if (status < 0)
6035 break;
6036 status = DRXX_Open(state);
6037 if (status < 0)
6038 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006039 /* added for test */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006040 msleep(30);
6041
6042 powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006043 status = CtrlPowerMode(state, &powerMode);
6044 if (status < 0)
6045 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006046
6047 /* Stamp driver version number in SCU data RAM in BCD code
6048 Done to enable field application engineers to retreive drxdriver version
6049 via I2C from SCU RAM.
6050 Not using SCU command interface for SCU register access since no
6051 microcode may be present.
Oliver Endrissebc7de22011-07-03 13:49:44 -03006052 */
6053 driverVersion =
6054 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6055 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6056 ((DRXK_VERSION_MAJOR % 10) << 4) +
6057 (DRXK_VERSION_MINOR % 10);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006058 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006059 if (status < 0)
6060 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006061 driverVersion =
6062 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6063 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6064 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6065 (DRXK_VERSION_PATCH % 10);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006066 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006067 if (status < 0)
6068 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006069
Oliver Endrissebc7de22011-07-03 13:49:44 -03006070 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6071 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6072 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006073
6074 /* Dirty fix of default values for ROM/PATCH microcode
6075 Dirty because this fix makes it impossible to setup suitable values
6076 before calling DRX_Open. This solution requires changes to RF AGC speed
6077 to be done via the CTRL function after calling DRX_Open */
6078
Oliver Endrissebc7de22011-07-03 13:49:44 -03006079 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006080
6081 /* Reset driver debug flags to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006082 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006083 if (status < 0)
6084 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006085 /* driver 0.9.0 */
6086 /* Setup FEC OC:
6087 NOTE: No more full FEC resets allowed afterwards!! */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006088 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006089 if (status < 0)
6090 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006091 /* MPEGTS functions are still the same */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006092 status = MPEGTSDtoInit(state);
6093 if (status < 0)
6094 break;
6095 status = MPEGTSStop(state);
6096 if (status < 0)
6097 break;
6098 status = MPEGTSConfigurePolarity(state);
6099 if (status < 0)
6100 break;
6101 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6102 if (status < 0)
6103 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006104 /* added: configure GPIO */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006105 status = WriteGPIO(state);
6106 if (status < 0)
6107 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006108
Oliver Endrissebc7de22011-07-03 13:49:44 -03006109 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006110
6111 if (state->m_bPowerDown) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006112 status = PowerDownDevice(state);
6113 if (status < 0)
6114 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006115 state->m_DrxkState = DRXK_POWERED_DOWN;
6116 } else
6117 state->m_DrxkState = DRXK_STOPPED;
6118 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006119 }
6120
6121 return 0;
6122}
6123
Oliver Endrissebc7de22011-07-03 13:49:44 -03006124static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006125{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006126 struct drxk_state *state = fe->demodulator_priv;
6127
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006128 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006129 kfree(state);
6130}
6131
Oliver Endrissebc7de22011-07-03 13:49:44 -03006132static int drxk_c_init(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");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006137 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006138 return -EBUSY;
6139 SetOperationMode(state, OM_QAM_ITU_A);
6140 return 0;
6141}
6142
Oliver Endrissebc7de22011-07-03 13:49:44 -03006143static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006144{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006145 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006146
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006147 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006148 ShutDown(state);
6149 mutex_unlock(&state->ctlock);
6150 return 0;
6151}
6152
Oliver Endrissebc7de22011-07-03 13:49:44 -03006153static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006154{
6155 struct drxk_state *state = fe->demodulator_priv;
6156
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006157 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006158 return ConfigureI2CBridge(state, enable ? true : false);
6159}
6160
Oliver Endrissebc7de22011-07-03 13:49:44 -03006161static int drxk_set_parameters(struct dvb_frontend *fe,
6162 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006163{
6164 struct drxk_state *state = fe->demodulator_priv;
6165 u32 IF;
6166
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006167 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006168 if (fe->ops.i2c_gate_ctrl)
6169 fe->ops.i2c_gate_ctrl(fe, 1);
6170 if (fe->ops.tuner_ops.set_params)
6171 fe->ops.tuner_ops.set_params(fe, p);
6172 if (fe->ops.i2c_gate_ctrl)
6173 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006174 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006175 fe->ops.tuner_ops.get_frequency(fe, &IF);
6176 Start(state, 0, IF);
6177
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006178 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006179
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006180 return 0;
6181}
6182
Oliver Endrissebc7de22011-07-03 13:49:44 -03006183static int drxk_c_get_frontend(struct dvb_frontend *fe,
6184 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006185{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006186 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006187 return 0;
6188}
6189
6190static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6191{
6192 struct drxk_state *state = fe->demodulator_priv;
6193 u32 stat;
6194
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006195 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006196 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006197 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006198 if (stat == MPEG_LOCK)
6199 *status |= 0x1f;
6200 if (stat == FEC_LOCK)
6201 *status |= 0x0f;
6202 if (stat == DEMOD_LOCK)
6203 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006204 return 0;
6205}
6206
6207static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6208{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006209 dprintk(1, "\n");
6210
Oliver Endrissebc7de22011-07-03 13:49:44 -03006211 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006212 return 0;
6213}
6214
Oliver Endrissebc7de22011-07-03 13:49:44 -03006215static int drxk_read_signal_strength(struct dvb_frontend *fe,
6216 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006217{
6218 struct drxk_state *state = fe->demodulator_priv;
6219 u32 val;
6220
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006221 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006222 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006223 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006224 return 0;
6225}
6226
6227static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6228{
6229 struct drxk_state *state = fe->demodulator_priv;
6230 s32 snr2;
6231
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006232 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006233 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006234 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006235 return 0;
6236}
6237
6238static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6239{
6240 struct drxk_state *state = fe->demodulator_priv;
6241 u16 err;
6242
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006243 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006244 DVBTQAMGetAccPktErr(state, &err);
6245 *ucblocks = (u32) err;
6246 return 0;
6247}
6248
Oliver Endrissebc7de22011-07-03 13:49:44 -03006249static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6250 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006251{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006252 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006253 sets->min_delay_ms = 3000;
6254 sets->max_drift = 0;
6255 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006256 return 0;
6257}
6258
Oliver Endrissebc7de22011-07-03 13:49:44 -03006259static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006260{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006261#if 0
6262 struct drxk_state *state = fe->demodulator_priv;
6263
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006264 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006265 kfree(state);
6266#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006267}
6268
Oliver Endrissebc7de22011-07-03 13:49:44 -03006269static int drxk_t_init(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");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006274 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006275 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006276 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006277 return 0;
6278}
6279
Oliver Endrissebc7de22011-07-03 13:49:44 -03006280static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006281{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006282 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006283
6284 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006285 mutex_unlock(&state->ctlock);
6286 return 0;
6287}
6288
Oliver Endrissebc7de22011-07-03 13:49:44 -03006289static int drxk_t_get_frontend(struct dvb_frontend *fe,
6290 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006291{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006292 dprintk(1, "\n");
6293
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006294 return 0;
6295}
6296
6297static struct dvb_frontend_ops drxk_c_ops = {
6298 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006299 .name = "DRXK DVB-C",
6300 .type = FE_QAM,
6301 .frequency_stepsize = 62500,
6302 .frequency_min = 47000000,
6303 .frequency_max = 862000000,
6304 .symbol_rate_min = 870000,
6305 .symbol_rate_max = 11700000,
6306 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6307 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006308 .release = drxk_c_release,
6309 .init = drxk_c_init,
6310 .sleep = drxk_c_sleep,
6311 .i2c_gate_ctrl = drxk_gate_ctrl,
6312
6313 .set_frontend = drxk_set_parameters,
6314 .get_frontend = drxk_c_get_frontend,
6315 .get_tune_settings = drxk_c_get_tune_settings,
6316
6317 .read_status = drxk_read_status,
6318 .read_ber = drxk_read_ber,
6319 .read_signal_strength = drxk_read_signal_strength,
6320 .read_snr = drxk_read_snr,
6321 .read_ucblocks = drxk_read_ucblocks,
6322};
6323
6324static struct dvb_frontend_ops drxk_t_ops = {
6325 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006326 .name = "DRXK DVB-T",
6327 .type = FE_OFDM,
6328 .frequency_min = 47125000,
6329 .frequency_max = 865000000,
6330 .frequency_stepsize = 166667,
6331 .frequency_tolerance = 0,
6332 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6333 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6334 FE_CAN_FEC_AUTO |
6335 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6336 FE_CAN_QAM_AUTO |
6337 FE_CAN_TRANSMISSION_MODE_AUTO |
6338 FE_CAN_GUARD_INTERVAL_AUTO |
6339 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006340 .release = drxk_t_release,
6341 .init = drxk_t_init,
6342 .sleep = drxk_t_sleep,
6343 .i2c_gate_ctrl = drxk_gate_ctrl,
6344
6345 .set_frontend = drxk_set_parameters,
6346 .get_frontend = drxk_t_get_frontend,
6347
6348 .read_status = drxk_read_status,
6349 .read_ber = drxk_read_ber,
6350 .read_signal_strength = drxk_read_signal_strength,
6351 .read_snr = drxk_read_snr,
6352 .read_ucblocks = drxk_read_ucblocks,
6353};
6354
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006355struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6356 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006357 struct dvb_frontend **fe_t)
6358{
6359 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006360 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006361
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006362 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006363 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006364 if (!state)
6365 return NULL;
6366
Oliver Endrissebc7de22011-07-03 13:49:44 -03006367 state->i2c = i2c;
6368 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006369 state->single_master = config->single_master;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006370
6371 mutex_init(&state->mutex);
6372 mutex_init(&state->ctlock);
6373
Oliver Endrissebc7de22011-07-03 13:49:44 -03006374 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6375 sizeof(struct dvb_frontend_ops));
6376 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6377 sizeof(struct dvb_frontend_ops));
6378 state->c_frontend.demodulator_priv = state;
6379 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006380
6381 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006382 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006383 goto error;
6384 *fe_t = &state->t_frontend;
6385 return &state->c_frontend;
6386
6387error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006388 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006389 kfree(state);
6390 return NULL;
6391}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006392EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006393
6394MODULE_DESCRIPTION("DRX-K driver");
6395MODULE_AUTHOR("Ralph Metzler");
6396MODULE_LICENSE("GPL");