blob: adb454a8eb7fd7c10a142bb52238cf77c4095f16 [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{
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300346 struct i2c_msg msgs[2] = {
347 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300348 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300349 {.addr = adr, .flags = I2C_M_RD,
350 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300351 };
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300352 dprintk(3, ":");
353 if (debug > 2) {
354 int i;
355 for (i = 0; i < len; i++)
356 printk(KERN_CONT " %02x", msg[i]);
357 printk(KERN_CONT "\n");
358 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300359 if (i2c_transfer(adap, msgs, 2) != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300360 if (debug > 2)
361 printk(KERN_CONT ": ERROR!\n");
362
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300363 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300364 return -1;
365 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300366 if (debug > 2) {
367 int i;
368 printk(KERN_CONT ": Read ");
369 for (i = 0; i < len; i++)
370 printk(KERN_CONT " %02x", msg[i]);
371 printk(KERN_CONT "\n");
372 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300373 return 0;
374}
375
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300376static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300377{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300378 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300379
380 if (state->single_master)
381 flags |= 0xC0;
382
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300383 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
384 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
385 mm1[1] = ((reg >> 16) & 0xFF);
386 mm1[2] = ((reg >> 24) & 0xFF) | flags;
387 mm1[3] = ((reg >> 7) & 0xFF);
388 len = 4;
389 } else {
390 mm1[0] = ((reg << 1) & 0xFF);
391 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
392 len = 2;
393 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300394 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300395 if (i2c_read(state->i2c, adr, mm1, len, mm2, 2) < 0)
396 return -1;
397 if (data)
398 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300399
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300400 return 0;
401}
402
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300403static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300404{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300405 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300406}
407
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300408static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300409{
410 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300411
412 if (state->single_master)
413 flags |= 0xC0;
414
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300415 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
416 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
417 mm1[1] = ((reg >> 16) & 0xFF);
418 mm1[2] = ((reg >> 24) & 0xFF) | flags;
419 mm1[3] = ((reg >> 7) & 0xFF);
420 len = 4;
421 } else {
422 mm1[0] = ((reg << 1) & 0xFF);
423 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
424 len = 2;
425 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300426 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300427 if (i2c_read(state->i2c, adr, mm1, len, mm2, 4) < 0)
428 return -1;
429 if (data)
430 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300431 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300432
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300433 return 0;
434}
435
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300436static int read32(struct drxk_state *state, u32 reg, u32 *data)
437{
438 return read32_flags(state, reg, data, 0);
439}
440
441static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300442{
443 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300444
445 if (state->single_master)
446 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300447 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
448 mm[0] = (((reg << 1) & 0xFF) | 0x01);
449 mm[1] = ((reg >> 16) & 0xFF);
450 mm[2] = ((reg >> 24) & 0xFF) | flags;
451 mm[3] = ((reg >> 7) & 0xFF);
452 len = 4;
453 } else {
454 mm[0] = ((reg << 1) & 0xFF);
455 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
456 len = 2;
457 }
458 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300459 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300460
461 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300462 if (i2c_write(state->i2c, adr, mm, len + 2) < 0)
463 return -1;
464 return 0;
465}
466
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300467static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300468{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300469 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300470}
471
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300472static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300473{
474 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300475
476 if (state->single_master)
477 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300478 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
479 mm[0] = (((reg << 1) & 0xFF) | 0x01);
480 mm[1] = ((reg >> 16) & 0xFF);
481 mm[2] = ((reg >> 24) & 0xFF) | flags;
482 mm[3] = ((reg >> 7) & 0xFF);
483 len = 4;
484 } else {
485 mm[0] = ((reg << 1) & 0xFF);
486 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
487 len = 2;
488 }
489 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300490 mm[len + 1] = (data >> 8) & 0xff;
491 mm[len + 2] = (data >> 16) & 0xff;
492 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300493 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300494 if (i2c_write(state->i2c, adr, mm, len + 4) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300495 return -1;
496 return 0;
497}
498
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300499static int write32(struct drxk_state *state, u32 reg, u32 data)
500{
501 return write32_flags(state, reg, data, 0);
502}
503
504static int write_block(struct drxk_state *state, u32 Address,
505 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300506{
507 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300508 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300509
510 if (state->single_master)
511 Flags |= 0xC0;
512
Oliver Endrissebc7de22011-07-03 13:49:44 -0300513 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300514 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300515 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300516 u8 *AdrBuf = &state->Chunk[0];
517 u32 AdrLength = 0;
518
Oliver Endrissebc7de22011-07-03 13:49:44 -0300519 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
520 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
521 AdrBuf[1] = ((Address >> 16) & 0xFF);
522 AdrBuf[2] = ((Address >> 24) & 0xFF);
523 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300524 AdrBuf[2] |= Flags;
525 AdrLength = 4;
526 if (Chunk == state->m_ChunkSize)
527 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300528 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300529 AdrBuf[0] = ((Address << 1) & 0xFF);
530 AdrBuf[1] = (((Address >> 16) & 0x0F) |
531 ((Address >> 18) & 0xF0));
532 AdrLength = 2;
533 }
534 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300535 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
536 if (debug > 1) {
537 int i;
538 if (pBlock)
539 for (i = 0; i < Chunk; i++)
540 printk(KERN_CONT " %02x", pBlock[i]);
541 printk(KERN_CONT "\n");
542 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300543 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300544 &state->Chunk[0], Chunk + AdrLength);
545 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300546 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
547 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300548 break;
549 }
550 pBlock += Chunk;
551 Address += (Chunk >> 1);
552 BlkSize -= Chunk;
553 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300554 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300555}
556
557#ifndef DRXK_MAX_RETRIES_POWERUP
558#define DRXK_MAX_RETRIES_POWERUP 20
559#endif
560
561int PowerUpDevice(struct drxk_state *state)
562{
563 int status;
564 u8 data = 0;
565 u16 retryCount = 0;
566
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300567 dprintk(1, "\n");
568
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300569 status = i2c_read1(state->i2c, state->demod_address, &data);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300570 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300571 do {
572 data = 0;
573 if (i2c_write(state->i2c,
574 state->demod_address, &data, 1) < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300575 printk(KERN_ERR "drxk: powerup failed\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300576 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300577 retryCount++;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300578 } while (i2c_read1(state->i2c,
579 state->demod_address, &data) < 0 &&
580 (retryCount < DRXK_MAX_RETRIES_POWERUP));
581 if (retryCount >= DRXK_MAX_RETRIES_POWERUP)
582 return -1;
583 do {
584 /* Make sure all clk domains are active */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300585 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300586 if (status < 0)
587 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300588 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300589 if (status < 0)
590 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300591 /* Enable pll lock tests */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300592 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300593 if (status < 0)
594 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300595 state->m_currentPowerMode = DRX_POWER_UP;
596 } while (0);
597 return status;
598}
599
600
601static int init_state(struct drxk_state *state)
602{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300603 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
604 u32 ulVSBIfAgcOutputLevel = 0;
605 u32 ulVSBIfAgcMinLevel = 0;
606 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
607 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300608
Oliver Endrissebc7de22011-07-03 13:49:44 -0300609 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
610 u32 ulVSBRfAgcOutputLevel = 0;
611 u32 ulVSBRfAgcMinLevel = 0;
612 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
613 u32 ulVSBRfAgcSpeed = 3;
614 u32 ulVSBRfAgcTop = 9500;
615 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300616
Oliver Endrissebc7de22011-07-03 13:49:44 -0300617 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
618 u32 ulATVIfAgcOutputLevel = 0;
619 u32 ulATVIfAgcMinLevel = 0;
620 u32 ulATVIfAgcMaxLevel = 0;
621 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300622
Oliver Endrissebc7de22011-07-03 13:49:44 -0300623 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
624 u32 ulATVRfAgcOutputLevel = 0;
625 u32 ulATVRfAgcMinLevel = 0;
626 u32 ulATVRfAgcMaxLevel = 0;
627 u32 ulATVRfAgcTop = 9500;
628 u32 ulATVRfAgcCutOffCurrent = 4000;
629 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300630
631 u32 ulQual83 = DEFAULT_MER_83;
632 u32 ulQual93 = DEFAULT_MER_93;
633
634 u32 ulDVBTStaticTSClock = 1;
635 u32 ulDVBCStaticTSClock = 1;
636
637 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
638 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
639
640 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
641 /* io_pad_cfg_mode output mode is drive always */
642 /* io_pad_cfg_drive is set to power 2 (23 mA) */
643 u32 ulGPIOCfg = 0x0113;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300644 u32 ulGPIO = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300645 u32 ulSerialMode = 1;
646 u32 ulInvertTSClock = 0;
647 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
648 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
649 u32 ulDVBTBitrate = 50000000;
650 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
651
652 u32 ulInsertRSByte = 0;
653
654 u32 ulRfMirror = 1;
655 u32 ulPowerDown = 0;
656
657 u32 ulAntennaDVBT = 1;
658 u32 ulAntennaDVBC = 0;
659 u32 ulAntennaSwitchDVBTDVBC = 0;
660
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300661 dprintk(1, "\n");
662
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300663 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300664 state->m_hasDVBT = false;
665 state->m_hasDVBC = false;
666 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300667 state->m_hasOOB = false;
668 state->m_hasAudio = false;
669
670 state->m_ChunkSize = 124;
671
672 state->m_oscClockFreq = 0;
673 state->m_smartAntInverted = false;
674 state->m_bPDownOpenBridge = false;
675
676 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300677 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300678 /* Timing div, 250ns/Psys */
679 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
680 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
681 HI_I2C_DELAY) / 1000;
682 /* Clipping */
683 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
684 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
685 state->m_HICfgWakeUpKey = (state->demod_address << 1);
686 /* port/bridge/power down ctrl */
687 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
688
689 state->m_bPowerDown = (ulPowerDown != 0);
690
691 state->m_DRXK_A1_PATCH_CODE = false;
692 state->m_DRXK_A1_ROM_CODE = false;
693 state->m_DRXK_A2_ROM_CODE = false;
694 state->m_DRXK_A3_ROM_CODE = false;
695 state->m_DRXK_A2_PATCH_CODE = false;
696 state->m_DRXK_A3_PATCH_CODE = false;
697
698 /* Init AGC and PGA parameters */
699 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300700 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
701 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
702 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
703 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
704 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300705 state->m_vsbPgaCfg = 140;
706
707 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300708 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
709 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
710 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
711 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
712 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
713 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
714 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
715 state->m_vsbPreSawCfg.reference = 0x07;
716 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300717
718 state->m_Quality83percent = DEFAULT_MER_83;
719 state->m_Quality93percent = DEFAULT_MER_93;
720 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
721 state->m_Quality83percent = ulQual83;
722 state->m_Quality93percent = ulQual93;
723 }
724
725 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300726 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
727 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
728 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
729 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
730 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300731
732 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300733 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
734 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
735 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
736 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
737 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
738 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
739 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
740 state->m_atvPreSawCfg.reference = 0x04;
741 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300742
743
744 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300745 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
746 state->m_dvbtRfAgcCfg.outputLevel = 0;
747 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
748 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
749 state->m_dvbtRfAgcCfg.top = 0x2100;
750 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
751 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300752
753
754 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300755 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
756 state->m_dvbtIfAgcCfg.outputLevel = 0;
757 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
758 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
759 state->m_dvbtIfAgcCfg.top = 13424;
760 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
761 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300762 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300763 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
764 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300765
Oliver Endrissebc7de22011-07-03 13:49:44 -0300766 state->m_dvbtPreSawCfg.reference = 4;
767 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300768
769 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300770 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
771 state->m_qamRfAgcCfg.outputLevel = 0;
772 state->m_qamRfAgcCfg.minOutputLevel = 6023;
773 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
774 state->m_qamRfAgcCfg.top = 0x2380;
775 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
776 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300777
778 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300779 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
780 state->m_qamIfAgcCfg.outputLevel = 0;
781 state->m_qamIfAgcCfg.minOutputLevel = 0;
782 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
783 state->m_qamIfAgcCfg.top = 0x0511;
784 state->m_qamIfAgcCfg.cutOffCurrent = 0;
785 state->m_qamIfAgcCfg.speed = 3;
786 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300787 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
788
Oliver Endrissebc7de22011-07-03 13:49:44 -0300789 state->m_qamPgaCfg = 140;
790 state->m_qamPreSawCfg.reference = 4;
791 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300792
793 state->m_OperationMode = OM_NONE;
794 state->m_DrxkState = DRXK_UNINITIALIZED;
795
796 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300797 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
798 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
799 state->m_enableParallel = true; /* If TRUE;
800 parallel out otherwise serial */
801 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
802 state->m_invertERR = false; /* If TRUE; invert ERR signal */
803 state->m_invertSTR = false; /* If TRUE; invert STR signals */
804 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
805 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300806 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300807 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300808 /* If TRUE; static MPEG clockrate will be used;
809 otherwise clockrate will adapt to the bitrate of the TS */
810
811 state->m_DVBTBitrate = ulDVBTBitrate;
812 state->m_DVBCBitrate = ulDVBCBitrate;
813
814 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
815 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
816
817 /* Maximum bitrate in b/s in case static clockrate is selected */
818 state->m_mpegTsStaticBitrate = 19392658;
819 state->m_disableTEIhandling = false;
820
821 if (ulInsertRSByte)
822 state->m_insertRSByte = true;
823
824 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
825 if (ulMpegLockTimeOut < 10000)
826 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
827 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
828 if (ulDemodLockTimeOut < 10000)
829 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
830
Oliver Endrissebc7de22011-07-03 13:49:44 -0300831 /* QAM defaults */
832 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300833 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300834 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
835 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300836
837 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
838 state->m_agcFastClipCtrlDelay = 0;
839
840 state->m_GPIOCfg = (ulGPIOCfg);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300841 state->m_GPIO = (ulGPIO == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300842
843 state->m_AntennaDVBT = (ulAntennaDVBT == 0 ? 0 : 1);
844 state->m_AntennaDVBC = (ulAntennaDVBC == 0 ? 0 : 1);
845 state->m_AntennaSwitchDVBTDVBC =
Oliver Endrissebc7de22011-07-03 13:49:44 -0300846 (ulAntennaSwitchDVBTDVBC == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300847
848 state->m_bPowerDown = false;
849 state->m_currentPowerMode = DRX_POWER_DOWN;
850
851 state->m_enableParallel = (ulSerialMode == 0);
852
853 state->m_rfmirror = (ulRfMirror == 0);
854 state->m_IfAgcPol = false;
855 return 0;
856}
857
858static int DRXX_Open(struct drxk_state *state)
859{
860 int status = 0;
861 u32 jtag = 0;
862 u16 bid = 0;
863 u16 key = 0;
864
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300865 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300866 do {
867 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300868 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300869 if (status < 0)
870 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300871 /* Check device id */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300872 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300873 if (status < 0)
874 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300875 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300876 if (status < 0)
877 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300878 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300879 if (status < 0)
880 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300881 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300882 if (status < 0)
883 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300884 status = write16(state, SIO_TOP_COMM_KEY__A, key);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300885 if (status < 0)
886 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300887 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300888 return status;
889}
890
891static int GetDeviceCapabilities(struct drxk_state *state)
892{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300893 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300894 u32 sioTopJtagidLo = 0;
895 int status;
896
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300897 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300898 do {
899 /* driver 0.9.0 */
900 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300901 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300902 if (status < 0)
903 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300904
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300905 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300906 if (status < 0)
907 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300908 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300909 if (status < 0)
910 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300911 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300912 if (status < 0)
913 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300914
915 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
916 case 0:
917 /* ignore (bypass ?) */
918 break;
919 case 1:
920 /* 27 MHz */
921 state->m_oscClockFreq = 27000;
922 break;
923 case 2:
924 /* 20.25 MHz */
925 state->m_oscClockFreq = 20250;
926 break;
927 case 3:
928 /* 4 MHz */
929 state->m_oscClockFreq = 20250;
930 break;
931 default:
932 return -1;
933 }
934 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300935 Determine device capabilities
936 Based on pinning v14
937 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300938 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300939 if (status < 0)
940 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300941 /* driver 0.9.0 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300942 switch ((sioTopJtagidLo >> 29) & 0xF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300943 case 0:
944 state->m_deviceSpin = DRXK_SPIN_A1;
945 break;
946 case 2:
947 state->m_deviceSpin = DRXK_SPIN_A2;
948 break;
949 case 3:
950 state->m_deviceSpin = DRXK_SPIN_A3;
951 break;
952 default:
953 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
954 status = -1;
955 break;
956 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300957 switch ((sioTopJtagidLo >> 12) & 0xFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300958 case 0x13:
959 /* typeId = DRX3913K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300960 state->m_hasLNA = false;
961 state->m_hasOOB = false;
962 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300963 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300964 state->m_hasDVBT = true;
965 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300966 state->m_hasSAWSW = true;
967 state->m_hasGPIO2 = false;
968 state->m_hasGPIO1 = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300969 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300970 break;
971 case 0x15:
972 /* typeId = DRX3915K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300973 state->m_hasLNA = false;
974 state->m_hasOOB = false;
975 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300976 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300977 state->m_hasDVBT = true;
978 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300979 state->m_hasSAWSW = true;
980 state->m_hasGPIO2 = true;
981 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300982 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300983 break;
984 case 0x16:
985 /* typeId = DRX3916K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300986 state->m_hasLNA = false;
987 state->m_hasOOB = false;
988 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300989 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300990 state->m_hasDVBT = true;
991 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300992 state->m_hasSAWSW = true;
993 state->m_hasGPIO2 = true;
994 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300995 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300996 break;
997 case 0x18:
998 /* typeId = DRX3918K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300999 state->m_hasLNA = false;
1000 state->m_hasOOB = false;
1001 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001002 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001003 state->m_hasDVBT = true;
1004 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001005 state->m_hasSAWSW = true;
1006 state->m_hasGPIO2 = true;
1007 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001008 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001009 break;
1010 case 0x21:
1011 /* typeId = DRX3921K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001012 state->m_hasLNA = false;
1013 state->m_hasOOB = false;
1014 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001015 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001016 state->m_hasDVBT = true;
1017 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001018 state->m_hasSAWSW = true;
1019 state->m_hasGPIO2 = true;
1020 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001021 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001022 break;
1023 case 0x23:
1024 /* typeId = DRX3923K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001025 state->m_hasLNA = false;
1026 state->m_hasOOB = false;
1027 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001028 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001029 state->m_hasDVBT = true;
1030 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001031 state->m_hasSAWSW = true;
1032 state->m_hasGPIO2 = true;
1033 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001034 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001035 break;
1036 case 0x25:
1037 /* typeId = DRX3925K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001038 state->m_hasLNA = false;
1039 state->m_hasOOB = false;
1040 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001041 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001042 state->m_hasDVBT = true;
1043 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001044 state->m_hasSAWSW = true;
1045 state->m_hasGPIO2 = true;
1046 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001047 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001048 break;
1049 case 0x26:
1050 /* typeId = DRX3926K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001051 state->m_hasLNA = false;
1052 state->m_hasOOB = false;
1053 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001054 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001055 state->m_hasDVBT = true;
1056 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001057 state->m_hasSAWSW = true;
1058 state->m_hasGPIO2 = true;
1059 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001060 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001061 break;
1062 default:
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001063 printk(KERN_ERR "drxk: DeviceID not supported = %02x\n",
Oliver Endrissebc7de22011-07-03 13:49:44 -03001064 ((sioTopJtagidLo >> 12) & 0xFF));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001065 status = -1;
1066 break;
1067 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001068 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001069 return status;
1070}
1071
1072static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1073{
1074 int status;
1075 bool powerdown_cmd;
1076
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001077 dprintk(1, "\n");
1078
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001079 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001080 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001081 if (status < 0)
1082 return status;
1083 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1084 msleep(1);
1085
1086 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001087 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1088 ((state->m_HICfgCtrl) &
1089 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1090 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001091 if (powerdown_cmd == false) {
1092 /* Wait until command rdy */
1093 u32 retryCount = 0;
1094 u16 waitCmd;
1095
1096 do {
1097 msleep(1);
1098 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001099 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1100 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001101 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1102 && (waitCmd != 0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001103
1104 if (status == 0)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001105 status = read16(state, SIO_HI_RA_RAM_RES__A,
1106 pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001107 }
1108 return status;
1109}
1110
1111static int HI_CfgCommand(struct drxk_state *state)
1112{
1113 int status;
1114
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001115 dprintk(1, "\n");
1116
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001117 mutex_lock(&state->mutex);
1118 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001119 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001120 if (status < 0)
1121 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001122 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001123 if (status < 0)
1124 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001125 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001126 if (status < 0)
1127 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001128 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001129 if (status < 0)
1130 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001131 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001132 if (status < 0)
1133 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001134 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 -03001135 if (status < 0)
1136 break;
1137 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1138 if (status < 0)
1139 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001140
1141 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001142 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001143 mutex_unlock(&state->mutex);
1144 return status;
1145}
1146
1147static int InitHI(struct drxk_state *state)
1148{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001149 dprintk(1, "\n");
1150
Oliver Endrissebc7de22011-07-03 13:49:44 -03001151 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001152 state->m_HICfgTimeout = 0x96FF;
1153 /* port/bridge/power down ctrl */
1154 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001155 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001156}
1157
1158static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1159{
1160 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001161 u16 sioPdrMclkCfg = 0;
1162 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001163
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001164 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001165 do {
1166 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001167 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001168 if (status < 0)
1169 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001170
1171 /* MPEG TS pad configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001172 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001173 if (status < 0)
1174 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001175
1176 if (mpegEnable == false) {
1177 /* Set MPEG TS pads to inputmode */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001178 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001179 if (status < 0)
1180 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001181 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001182 if (status < 0)
1183 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001184 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001185 if (status < 0)
1186 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001187 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001188 if (status < 0)
1189 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001190 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001191 if (status < 0)
1192 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001193 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001194 if (status < 0)
1195 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001196 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001197 if (status < 0)
1198 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001199 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001200 if (status < 0)
1201 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001202 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001203 if (status < 0)
1204 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001205 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001206 if (status < 0)
1207 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001208 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001209 if (status < 0)
1210 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001211 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001212 if (status < 0)
1213 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001214 } else {
1215 /* Enable MPEG output */
1216 sioPdrMdxCfg =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001217 ((state->m_TSDataStrength <<
1218 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001219 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03001220 SIO_PDR_MCLK_CFG_DRIVE__B) |
1221 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001222
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001223 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001224 if (status < 0)
1225 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001226 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001227 if (status < 0)
1228 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001229 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001230 if (status < 0)
1231 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001232 if (state->m_enableParallel == true) {
1233 /* paralel -> enable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001234 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001235 if (status < 0)
1236 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001237 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001238 if (status < 0)
1239 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001240 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001241 if (status < 0)
1242 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001243 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001244 if (status < 0)
1245 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001246 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001247 if (status < 0)
1248 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001249 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001250 if (status < 0)
1251 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001252 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001253 if (status < 0)
1254 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001255 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001256 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1257 SIO_PDR_MD0_CFG_DRIVE__B)
1258 | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001259 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001260 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001261 if (status < 0)
1262 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001263 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001264 if (status < 0)
1265 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001266 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001267 if (status < 0)
1268 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001269 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001270 if (status < 0)
1271 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001272 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001273 if (status < 0)
1274 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001275 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001276 if (status < 0)
1277 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001278 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001279 if (status < 0)
1280 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001281 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001282 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001283 if (status < 0)
1284 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001285 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001286 if (status < 0)
1287 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001288 }
1289 /* Enable MB output over MPEG pads and ctl input */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001290 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001291 if (status < 0)
1292 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001293 /* Write nomagic word to enable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001294 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001295 if (status < 0)
1296 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001297 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001298 return status;
1299}
1300
1301static int MPEGTSDisable(struct drxk_state *state)
1302{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001303 dprintk(1, "\n");
1304
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001305 return MPEGTSConfigurePins(state, false);
1306}
1307
1308static int BLChainCmd(struct drxk_state *state,
1309 u16 romOffset, u16 nrOfElements, u32 timeOut)
1310{
1311 u16 blStatus = 0;
1312 int status;
1313 unsigned long end;
1314
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001315 dprintk(1, "\n");
1316
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001317 mutex_lock(&state->mutex);
1318 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001319 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001320 if (status < 0)
1321 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001322 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001323 if (status < 0)
1324 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001325 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001326 if (status < 0)
1327 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001328 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001329 if (status < 0)
1330 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001331 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001332
1333 do {
1334 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001335 status = read16(state, SIO_BL_STATUS__A, &blStatus);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001336 if (status < 0)
1337 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001338 } while ((blStatus == 0x1) &&
1339 ((time_is_after_jiffies(end))));
1340 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001341 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001342 mutex_unlock(&state->mutex);
1343 return -1;
1344 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001345 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001346 mutex_unlock(&state->mutex);
1347 return status;
1348}
1349
1350
1351static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001352 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001353{
1354 const u8 *pSrc = pMCImage;
1355 u16 Flags;
1356 u16 Drain;
1357 u32 Address;
1358 u16 nBlocks;
1359 u16 BlockSize;
1360 u16 BlockCRC;
1361 u32 offset = 0;
1362 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001363 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001364
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001365 dprintk(1, "\n");
1366
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001367 /* down the drain (we don care about MAGIC_WORD) */
1368 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001369 pSrc += sizeof(u16);
1370 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001371 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001372 pSrc += sizeof(u16);
1373 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001374
1375 for (i = 0; i < nBlocks; i += 1) {
1376 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001377 (pSrc[2] << 8) | pSrc[3];
1378 pSrc += sizeof(u32);
1379 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001380
1381 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001382 pSrc += sizeof(u16);
1383 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001384
1385 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001386 pSrc += sizeof(u16);
1387 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001388
1389 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001390 pSrc += sizeof(u16);
1391 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001392
1393 if (offset + BlockSize > Length) {
1394 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1395 return -EINVAL;
1396 }
1397
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001398 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001399 if (status < 0) {
1400 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001401 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001402 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001403 pSrc += BlockSize;
1404 offset += BlockSize;
1405 }
1406 return status;
1407}
1408
1409static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1410{
1411 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001412 u16 data = 0;
1413 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001414 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1415 unsigned long end;
1416
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001417 dprintk(1, "\n");
1418
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001419 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001420 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001421 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1422 }
1423
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001424 status = (read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001425
1426 if (data == desiredStatus) {
1427 /* tokenring already has correct status */
1428 return status;
1429 }
1430 /* Disable/enable dvbt tokenring bridge */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001431 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001432 write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001433
Oliver Endrissebc7de22011-07-03 13:49:44 -03001434 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001435 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001436 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001437 if (status < 0)
1438 break;
1439 } while ((data != desiredStatus) && ((time_is_after_jiffies(end))));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001440 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001441 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001442 return -1;
1443 }
1444 return status;
1445}
1446
1447static int MPEGTSStop(struct drxk_state *state)
1448{
1449 int status = 0;
1450 u16 fecOcSncMode = 0;
1451 u16 fecOcIprMode = 0;
1452
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001453 dprintk(1, "\n");
1454
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001455 do {
1456 /* Gracefull shutdown (byte boundaries) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001457 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001458 if (status < 0)
1459 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001460 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001461 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001462 if (status < 0)
1463 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001464
1465 /* Suppress MCLK during absence of data */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001466 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001467 if (status < 0)
1468 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001469 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001470 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001471 if (status < 0)
1472 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001473 } while (0);
1474 return status;
1475}
1476
1477static int scu_command(struct drxk_state *state,
1478 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001479 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001480{
1481#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1482#error DRXK register mapping no longer compatible with this routine!
1483#endif
1484 u16 curCmd = 0;
1485 int status;
1486 unsigned long end;
1487
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001488 dprintk(1, "\n");
1489
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001490 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1491 ((resultLen > 0) && (result == NULL)))
1492 return -1;
1493
1494 mutex_lock(&state->mutex);
1495 do {
1496 /* assume that the command register is ready
1497 since it is checked afterwards */
1498 u8 buffer[34];
1499 int cnt = 0, ii;
1500
Oliver Endrissebc7de22011-07-03 13:49:44 -03001501 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001502 buffer[cnt++] = (parameter[ii] & 0xFF);
1503 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1504 }
1505 buffer[cnt++] = (cmd & 0xFF);
1506 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1507
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001508 write_block(state, SCU_RAM_PARAM_0__A -
1509 (parameterLen - 1), cnt, buffer);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001510 /* Wait until SCU has processed command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001511 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001512 do {
1513 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001514 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001515 if (status < 0)
1516 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001517 } while (!(curCmd == DRX_SCU_READY)
1518 && (time_is_after_jiffies(end)));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001519 if (curCmd != DRX_SCU_READY) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001520 printk(KERN_ERR "drxk: SCU not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001521 mutex_unlock(&state->mutex);
1522 return -1;
1523 }
1524 /* read results */
1525 if ((resultLen > 0) && (result != NULL)) {
1526 s16 err;
1527 int ii;
1528
Oliver Endrissebc7de22011-07-03 13:49:44 -03001529 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001530 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001531 if (status < 0)
1532 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001533 }
1534
1535 /* Check if an error was reported by SCU */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001536 err = (s16) result[0];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001537
1538 /* check a few fixed error codes */
1539 if (err == SCU_RESULT_UNKSTD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001540 printk(KERN_ERR "drxk: SCU_RESULT_UNKSTD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001541 mutex_unlock(&state->mutex);
1542 return -1;
1543 } else if (err == SCU_RESULT_UNKCMD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001544 printk(KERN_ERR "drxk: SCU_RESULT_UNKCMD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001545 mutex_unlock(&state->mutex);
1546 return -1;
1547 }
1548 /* here it is assumed that negative means error,
1549 and positive no error */
1550 else if (err < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001551 printk(KERN_ERR "drxk: %s ERROR\n", __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001552 mutex_unlock(&state->mutex);
1553 return -1;
1554 }
1555 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001556 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001557 mutex_unlock(&state->mutex);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001558 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001559 printk(KERN_ERR "drxk: %s: status = %d\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001560
1561 return status;
1562}
1563
1564static int SetIqmAf(struct drxk_state *state, bool active)
1565{
1566 u16 data = 0;
1567 int status;
1568
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001569 dprintk(1, "\n");
1570
Oliver Endrissebc7de22011-07-03 13:49:44 -03001571 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001572 /* Configure IQM */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001573 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001574 if (status < 0)
1575 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001576 if (!active) {
1577 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1578 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1579 | IQM_AF_STDBY_STDBY_PD_STANDBY
1580 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
Oliver Endrissebc7de22011-07-03 13:49:44 -03001581 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1582 } else { /* active */
1583
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001584 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1585 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1586 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1587 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1588 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
Oliver Endrissebc7de22011-07-03 13:49:44 -03001589 );
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001590 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001591 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001592 if (status < 0)
1593 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001594 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001595 return status;
1596}
1597
Oliver Endrissebc7de22011-07-03 13:49:44 -03001598static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001599{
1600 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001601 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001602
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001603 dprintk(1, "\n");
1604
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001605 /* Check arguments */
1606 if (mode == NULL)
1607 return -1;
1608
1609 switch (*mode) {
1610 case DRX_POWER_UP:
1611 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1612 break;
1613 case DRXK_POWER_DOWN_OFDM:
1614 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1615 break;
1616 case DRXK_POWER_DOWN_CORE:
1617 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1618 break;
1619 case DRXK_POWER_DOWN_PLL:
1620 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1621 break;
1622 case DRX_POWER_DOWN:
1623 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1624 break;
1625 default:
1626 /* Unknow sleep mode */
1627 return -1;
1628 break;
1629 }
1630
1631 /* If already in requested power mode, do nothing */
1632 if (state->m_currentPowerMode == *mode)
1633 return 0;
1634
1635 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001636 if (state->m_currentPowerMode != DRX_POWER_UP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001637 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001638 status = PowerUpDevice(state);
1639 if (status < 0)
1640 break;
1641 status = DVBTEnableOFDMTokenRing(state, true);
1642 if (status < 0)
1643 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001644 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001645 }
1646
1647 if (*mode == DRX_POWER_UP) {
1648 /* Restore analog & pin configuartion */
1649 } else {
1650 /* Power down to requested mode */
1651 /* Backup some register settings */
1652 /* Set pins with possible pull-ups connected
1653 to them in input mode */
1654 /* Analog power down */
1655 /* ADC power down */
1656 /* Power down device */
1657 /* stop all comm_exec */
1658 /* Stop and power down previous standard */
1659 do {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001660 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001661 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001662 status = MPEGTSStop(state);
1663 if (status < 0)
1664 break;
1665 status = PowerDownDVBT(state, false);
1666 if (status < 0)
1667 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001668 break;
1669 case OM_QAM_ITU_A:
1670 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001671 status = MPEGTSStop(state);
1672 if (status < 0)
1673 break;
1674 status = PowerDownQAM(state);
1675 if (status < 0)
1676 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001677 break;
1678 default:
1679 break;
1680 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001681 status = DVBTEnableOFDMTokenRing(state, false);
1682 if (status < 0)
1683 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001684 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001685 if (status < 0)
1686 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001687 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001688 if (status < 0)
1689 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001690
Oliver Endrissebc7de22011-07-03 13:49:44 -03001691 if (*mode != DRXK_POWER_DOWN_OFDM) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001692 state->m_HICfgCtrl |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03001693 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001694 status = HI_CfgCommand(state);
1695 if (status < 0)
1696 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001697 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001698 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001699 }
1700 state->m_currentPowerMode = *mode;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001701 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001702}
1703
1704static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1705{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001706 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001707 u16 cmdResult = 0;
1708 u16 data = 0;
1709 int status;
1710
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001711 dprintk(1, "\n");
1712
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001713 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001714 status = read16(state, SCU_COMM_EXEC__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001715 if (status < 0)
1716 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001717 if (data == SCU_COMM_EXEC_ACTIVE) {
1718 /* Send OFDM stop command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001719 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
1720 if (status < 0)
1721 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001722 /* Send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001723 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1724 if (status < 0)
1725 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001726 }
1727
1728 /* Reset datapath for OFDM, processors first */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001729 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001730 if (status < 0)
1731 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001732 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001733 if (status < 0)
1734 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001735 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001736 if (status < 0)
1737 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001738
1739 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001740 status = SetIqmAf(state, false);
1741 if (status < 0)
1742 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001743
1744 /* powerdown to OFDM mode */
1745 if (setPowerMode) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001746 status = CtrlPowerMode(state, &powerMode);
1747 if (status < 0)
1748 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001749 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001750 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001751 return status;
1752}
1753
Oliver Endrissebc7de22011-07-03 13:49:44 -03001754static int SetOperationMode(struct drxk_state *state,
1755 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001756{
1757 int status = 0;
1758
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001759 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001760 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001761 Stop and power down previous standard
1762 TODO investigate total power down instead of partial
1763 power down depending on "previous" standard.
1764 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001765 do {
1766 /* disable HW lock indicator */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001767 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001768 if (status < 0)
1769 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001770
1771 if (state->m_OperationMode != oMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001772 switch (state->m_OperationMode) {
1773 /* OM_NONE was added for start up */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001774 case OM_NONE:
1775 break;
1776 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001777 status = MPEGTSStop(state);
1778 if (status < 0)
1779 break;
1780 status = PowerDownDVBT(state, true);
1781 if (status < 0)
1782 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001783 state->m_OperationMode = OM_NONE;
1784 break;
1785 case OM_QAM_ITU_B:
1786 status = -1;
1787 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001788 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001789 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001790 status = MPEGTSStop(state);
1791 if (status < 0)
1792 break;
1793 status = PowerDownQAM(state);
1794 if (status < 0)
1795 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001796 state->m_OperationMode = OM_NONE;
1797 break;
1798 default:
1799 status = -1;
1800 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001801 status = status;
1802 if (status < 0)
1803 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001804
1805 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001806 Power up new standard
1807 */
1808 switch (oMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001809 case OM_DVBT:
1810 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001811 status = SetDVBTStandard(state, oMode);
1812 if (status < 0)
1813 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001814 break;
1815 case OM_QAM_ITU_B:
1816 status = -1;
1817 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001818 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001819 case OM_QAM_ITU_C:
1820 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001821 status = SetQAMStandard(state, oMode);
1822 if (status < 0)
1823 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001824 break;
1825 default:
1826 status = -1;
1827 }
1828 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001829 status = status;
1830 if (status < 0)
1831 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001832 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001833 return 0;
1834}
1835
1836static int Start(struct drxk_state *state, s32 offsetFreq,
1837 s32 IntermediateFrequency)
1838{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001839 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001840
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001841 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001842 do {
1843 u16 IFreqkHz;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001844 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001845
1846 if (state->m_DrxkState != DRXK_STOPPED &&
1847 state->m_DrxkState != DRXK_DTV_STARTED) {
1848 status = -1;
1849 break;
1850 }
1851 state->m_bMirrorFreqSpect =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001852 (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001853
1854 if (IntermediateFrequency < 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001855 state->m_bMirrorFreqSpect =
1856 !state->m_bMirrorFreqSpect;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001857 IntermediateFrequency = -IntermediateFrequency;
1858 }
1859
Oliver Endrissebc7de22011-07-03 13:49:44 -03001860 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001861 case OM_QAM_ITU_A:
1862 case OM_QAM_ITU_C:
1863 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001864 status = SetQAM(state, IFreqkHz, OffsetkHz);
1865 if (status < 0)
1866 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001867 state->m_DrxkState = DRXK_DTV_STARTED;
1868 break;
1869 case OM_DVBT:
1870 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001871 status = MPEGTSStop(state);
1872 if (status < 0)
1873 break;
1874 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1875 if (status < 0)
1876 break;
1877 status = DVBTStart(state);
1878 if (status < 0)
1879 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001880 state->m_DrxkState = DRXK_DTV_STARTED;
1881 break;
1882 default:
1883 break;
1884 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001885 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001886 return status;
1887}
1888
1889static int ShutDown(struct drxk_state *state)
1890{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001891 dprintk(1, "\n");
1892
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001893 MPEGTSStop(state);
1894 return 0;
1895}
1896
Oliver Endrissebc7de22011-07-03 13:49:44 -03001897static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1898 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001899{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001900 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001901
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001902 dprintk(1, "\n");
1903
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001904 if (pLockStatus == NULL)
1905 return -1;
1906
1907 *pLockStatus = NOT_LOCKED;
1908
1909 /* define the SCU command code */
1910 switch (state->m_OperationMode) {
1911 case OM_QAM_ITU_A:
1912 case OM_QAM_ITU_B:
1913 case OM_QAM_ITU_C:
1914 status = GetQAMLockStatus(state, pLockStatus);
1915 break;
1916 case OM_DVBT:
1917 status = GetDVBTLockStatus(state, pLockStatus);
1918 break;
1919 default:
1920 break;
1921 }
1922 return status;
1923}
1924
1925static int MPEGTSStart(struct drxk_state *state)
1926{
1927 int status = 0;
1928
1929 u16 fecOcSncMode = 0;
1930
1931 do {
1932 /* Allow OC to sync again */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001933 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001934 if (status < 0)
1935 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001936 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001937 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001938 if (status < 0)
1939 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001940 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001941 if (status < 0)
1942 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001943 } while (0);
1944 return status;
1945}
1946
1947static int MPEGTSDtoInit(struct drxk_state *state)
1948{
1949 int status = -1;
1950
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001951 dprintk(1, "\n");
1952
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001953 do {
1954 /* Rate integration settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001955 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001956 if (status < 0)
1957 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001958 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001959 if (status < 0)
1960 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001961 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001962 if (status < 0)
1963 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001964 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001965 if (status < 0)
1966 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001967 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001968 if (status < 0)
1969 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001970 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001971 if (status < 0)
1972 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001973 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001974 if (status < 0)
1975 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001976 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001977 if (status < 0)
1978 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001979
1980 /* Additional configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001981 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001982 if (status < 0)
1983 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001984 status = write16(state, FEC_OC_SNC_LWM__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001985 if (status < 0)
1986 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001987 status = write16(state, FEC_OC_SNC_HWM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001988 if (status < 0)
1989 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001990 } while (0);
1991 return status;
1992}
1993
Oliver Endrissebc7de22011-07-03 13:49:44 -03001994static int MPEGTSDtoSetup(struct drxk_state *state,
1995 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001996{
1997 int status = -1;
1998
Oliver Endrissebc7de22011-07-03 13:49:44 -03001999 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2000 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2001 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2002 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2003 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2004 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2005 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002006 u16 fecOcTmdMode = 0;
2007 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002008 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002009 bool staticCLK = false;
2010
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002011 dprintk(1, "\n");
2012
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002013 do {
2014 /* Check insertion of the Reed-Solomon parity bytes */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002015 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002016 if (status < 0)
2017 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002018 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002019 if (status < 0)
2020 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002021 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002022 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2023 if (state->m_insertRSByte == true) {
2024 /* enable parity symbol forward */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002025 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002026 /* MVAL disable during parity bytes */
2027 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2028 /* TS burst length to 204 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002029 fecOcDtoBurstLen = 204;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002030 }
2031
2032 /* Check serial or parrallel output */
2033 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2034 if (state->m_enableParallel == false) {
2035 /* MPEG data output is serial -> set ipr_mode[0] */
2036 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2037 }
2038
2039 switch (oMode) {
2040 case OM_DVBT:
2041 maxBitRate = state->m_DVBTBitrate;
2042 fecOcTmdMode = 3;
2043 fecOcRcnCtlRate = 0xC00000;
2044 staticCLK = state->m_DVBTStaticCLK;
2045 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002046 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002047 case OM_QAM_ITU_C:
2048 fecOcTmdMode = 0x0004;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002049 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002050 maxBitRate = state->m_DVBCBitrate;
2051 staticCLK = state->m_DVBCStaticCLK;
2052 break;
2053 default:
2054 status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002055 } /* switch (standard) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002056 status = status;
2057 if (status < 0)
2058 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002059
2060 /* Configure DTO's */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002061 if (staticCLK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002062 u32 bitRate = 0;
2063
2064 /* Rational DTO for MCLK source (static MCLK rate),
2065 Dynamic DTO for optimal grouping
2066 (avoid intra-packet gaps),
2067 DTO offset enable to sync TS burst with MSTRT */
2068 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2069 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2070 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2071 FEC_OC_FCT_MODE_VIRT_ENA__M);
2072
2073 /* Check user defined bitrate */
2074 bitRate = maxBitRate;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002075 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002076 bitRate = 75900000UL;
2077 }
2078 /* Rational DTO period:
2079 dto_period = (Fsys / bitrate) - 2
2080
2081 Result should be floored,
2082 to make sure >= requested bitrate
Oliver Endrissebc7de22011-07-03 13:49:44 -03002083 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002084 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2085 * 1000) / bitRate);
2086 if (fecOcDtoPeriod <= 2)
2087 fecOcDtoPeriod = 0;
2088 else
2089 fecOcDtoPeriod -= 2;
2090 fecOcTmdIntUpdRate = 8;
2091 } else {
2092 /* (commonAttr->staticCLK == false) => dynamic mode */
2093 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2094 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2095 fecOcTmdIntUpdRate = 5;
2096 }
2097
2098 /* Write appropriate registers with requested configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002099 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002100 if (status < 0)
2101 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002102 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002103 if (status < 0)
2104 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002105 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002106 if (status < 0)
2107 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002108 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002109 if (status < 0)
2110 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002111 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002112 if (status < 0)
2113 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002114 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002115 if (status < 0)
2116 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002117
2118 /* Rate integration settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002119 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002120 if (status < 0)
2121 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002122 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002123 if (status < 0)
2124 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002125 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002126 if (status < 0)
2127 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002128 } while (0);
2129 return status;
2130}
2131
2132static int MPEGTSConfigurePolarity(struct drxk_state *state)
2133{
2134 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002135 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002136
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002137 dprintk(1, "\n");
2138
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002139 /* Data mask for the output data byte */
2140 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002141 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2142 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2143 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2144 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002145
2146 /* Control selective inversion of output bits */
2147 fecOcRegIprInvert &= (~(InvertDataMask));
2148 if (state->m_invertDATA == true)
2149 fecOcRegIprInvert |= InvertDataMask;
2150 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2151 if (state->m_invertERR == true)
2152 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2153 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2154 if (state->m_invertSTR == true)
2155 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2156 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2157 if (state->m_invertVAL == true)
2158 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2159 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2160 if (state->m_invertCLK == true)
2161 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002162 status = write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002163 return status;
2164}
2165
2166#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2167
2168static int SetAgcRf(struct drxk_state *state,
2169 struct SCfgAgc *pAgcCfg, bool isDTV)
2170{
2171 int status = 0;
2172 struct SCfgAgc *pIfAgcSettings;
2173
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002174 dprintk(1, "\n");
2175
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002176 if (pAgcCfg == NULL)
2177 return -1;
2178
2179 do {
2180 u16 data = 0;
2181
2182 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002183 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002184
2185 /* Enable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002186 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002187 if (status < 0)
2188 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002189 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002190 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002191 if (status < 0)
2192 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002193
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002194 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002195 if (status < 0)
2196 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002197
2198 /* Enable SCU RF AGC loop */
2199 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2200
2201 /* Polarity */
2202 if (state->m_RfAgcPol)
2203 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2204 else
2205 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002206 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002207 if (status < 0)
2208 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002209
2210 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002211 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002212 if (status < 0)
2213 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002214
2215 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2216 data |= (~(pAgcCfg->speed <<
2217 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2218 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2219
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002220 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002221 if (status < 0)
2222 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002223
2224 if (IsDVBT(state))
2225 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2226 else if (IsQAM(state))
2227 pIfAgcSettings = &state->m_qamIfAgcCfg;
2228 else
2229 pIfAgcSettings = &state->m_atvIfAgcCfg;
2230 if (pIfAgcSettings == NULL)
2231 return -1;
2232
2233 /* Set TOP, only if IF-AGC is in AUTO mode */
2234 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002235 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002236 if (status < 0)
2237 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002238
2239 /* Cut-Off current */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002240 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002241 if (status < 0)
2242 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002243
2244 /* Max. output level */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002245 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002246 if (status < 0)
2247 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002248
2249 break;
2250
2251 case DRXK_AGC_CTRL_USER:
2252 /* Enable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002253 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002254 if (status < 0)
2255 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002256 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002257 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002258 if (status < 0)
2259 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002260
2261 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002262 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002263 if (status < 0)
2264 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002265 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2266 if (state->m_RfAgcPol)
2267 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2268 else
2269 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002270 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002271 if (status < 0)
2272 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002273
2274 /* SCU c.o.c. to 0, enabling full control range */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002275 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002276 if (status < 0)
2277 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002278
2279 /* Write value to output pin */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002280 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002281 if (status < 0)
2282 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002283 break;
2284
Oliver Endrissebc7de22011-07-03 13:49:44 -03002285 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002286 /* Disable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002287 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002288 if (status < 0)
2289 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002290 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002291 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002292 if (status < 0)
2293 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002294
2295 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002296 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002297 if (status < 0)
2298 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002299 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002300 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002301 if (status < 0)
2302 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002303 break;
2304
2305 default:
2306 return -1;
2307
Oliver Endrissebc7de22011-07-03 13:49:44 -03002308 } /* switch (agcsettings->ctrlMode) */
2309 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002310 return status;
2311}
2312
2313#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2314
Oliver Endrissebc7de22011-07-03 13:49:44 -03002315static int SetAgcIf(struct drxk_state *state,
2316 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002317{
2318 u16 data = 0;
2319 int status = 0;
2320 struct SCfgAgc *pRfAgcSettings;
2321
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002322 dprintk(1, "\n");
2323
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002324 do {
2325 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002326 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002327
2328 /* Enable IF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002329 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002330 if (status < 0)
2331 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002332 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002333 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002334 if (status < 0)
2335 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002336
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002337 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002338 if (status < 0)
2339 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002340
2341 /* Enable SCU IF AGC loop */
2342 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2343
2344 /* Polarity */
2345 if (state->m_IfAgcPol)
2346 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2347 else
2348 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002349 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002350 if (status < 0)
2351 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002352
2353 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002354 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002355 if (status < 0)
2356 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002357 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2358 data |= (~(pAgcCfg->speed <<
2359 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2360 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2361
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002362 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002363 if (status < 0)
2364 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002365
2366 if (IsQAM(state))
2367 pRfAgcSettings = &state->m_qamRfAgcCfg;
2368 else
2369 pRfAgcSettings = &state->m_atvRfAgcCfg;
2370 if (pRfAgcSettings == NULL)
2371 return -1;
2372 /* Restore TOP */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002373 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002374 if (status < 0)
2375 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002376 break;
2377
Oliver Endrissebc7de22011-07-03 13:49:44 -03002378 case DRXK_AGC_CTRL_USER:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002379
2380 /* Enable IF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002381 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002382 if (status < 0)
2383 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002384 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002385 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002386 if (status < 0)
2387 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002388
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002389 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002390 if (status < 0)
2391 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002392
2393 /* Disable SCU IF AGC loop */
2394 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2395
2396 /* Polarity */
2397 if (state->m_IfAgcPol)
2398 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2399 else
2400 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002401 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002402 if (status < 0)
2403 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002404
2405 /* Write value to output pin */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002406 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002407 if (status < 0)
2408 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002409 break;
2410
Oliver Endrissebc7de22011-07-03 13:49:44 -03002411 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002412
2413 /* Disable If AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002414 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002415 if (status < 0)
2416 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002417 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002418 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002419 if (status < 0)
2420 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002421
2422 /* Disable SCU IF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002423 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002424 if (status < 0)
2425 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002426 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002427 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002428 if (status < 0)
2429 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002430 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002431 } /* switch (agcSettingsIf->ctrlMode) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002432
2433 /* always set the top to support
2434 configurations without if-loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002435 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002436 if (status < 0)
2437 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002438
2439
Oliver Endrissebc7de22011-07-03 13:49:44 -03002440 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002441 return status;
2442}
2443
2444static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2445{
2446 u16 agcDacLvl;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002447 int status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002448
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002449 dprintk(1, "\n");
2450
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002451 *pValue = 0;
2452
Oliver Endrissebc7de22011-07-03 13:49:44 -03002453 if (status == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002454 u16 Level = 0;
2455 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2456 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2457 if (Level < 14000)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002458 *pValue = (14000 - Level) / 4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002459 else
2460 *pValue = 0;
2461 }
2462 return status;
2463}
2464
Oliver Endrissebc7de22011-07-03 13:49:44 -03002465static int GetQAMSignalToNoise(struct drxk_state *state,
2466 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002467{
2468 int status = 0;
2469
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002470 dprintk(1, "\n");
2471
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002472 do {
2473 /* MER calculation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002474 u16 qamSlErrPower = 0; /* accum. error between
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002475 raw and sliced symbols */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002476 u32 qamSlSigPower = 0; /* used for MER, depends of
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002477 QAM constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002478 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002479
2480 /* get the register value needed for MER */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002481 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002482 if (status < 0)
2483 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002484
Oliver Endrissebc7de22011-07-03 13:49:44 -03002485 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002486 case QAM_16:
2487 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2488 break;
2489 case QAM_32:
2490 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2491 break;
2492 case QAM_64:
2493 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2494 break;
2495 case QAM_128:
2496 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2497 break;
2498 default:
2499 case QAM_256:
2500 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2501 break;
2502 }
2503
2504 if (qamSlErrPower > 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002505 qamSlMer = Log10Times100(qamSlSigPower) -
2506 Log10Times100((u32) qamSlErrPower);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002507 }
2508 *pSignalToNoise = qamSlMer;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002509 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002510 return status;
2511}
2512
Oliver Endrissebc7de22011-07-03 13:49:44 -03002513static int GetDVBTSignalToNoise(struct drxk_state *state,
2514 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002515{
2516 int status = 0;
2517
Oliver Endrissebc7de22011-07-03 13:49:44 -03002518 u16 regData = 0;
2519 u32 EqRegTdSqrErrI = 0;
2520 u32 EqRegTdSqrErrQ = 0;
2521 u16 EqRegTdSqrErrExp = 0;
2522 u16 EqRegTdTpsPwrOfs = 0;
2523 u16 EqRegTdReqSmbCnt = 0;
2524 u32 tpsCnt = 0;
2525 u32 SqrErrIQ = 0;
2526 u32 a = 0;
2527 u32 b = 0;
2528 u32 c = 0;
2529 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002530 u16 transmissionParams = 0;
2531
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002532 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002533 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002534 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002535 if (status < 0)
2536 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002537 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002538 if (status < 0)
2539 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002540 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002541 if (status < 0)
2542 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002543 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002544 if (status < 0)
2545 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002546 /* Extend SQR_ERR_I operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002547 EqRegTdSqrErrI = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002548 if ((EqRegTdSqrErrExp > 11) &&
2549 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2550 EqRegTdSqrErrI += 0x00010000UL;
2551 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002552 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002553 if (status < 0)
2554 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002555 /* Extend SQR_ERR_Q operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002556 EqRegTdSqrErrQ = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002557 if ((EqRegTdSqrErrExp > 11) &&
2558 (EqRegTdSqrErrQ < 0x00000FFFUL))
2559 EqRegTdSqrErrQ += 0x00010000UL;
2560
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002561 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002562 if (status < 0)
2563 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002564
2565 /* Check input data for MER */
2566
2567 /* MER calculation (in 0.1 dB) without math.h */
2568 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2569 iMER = 0;
2570 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2571 /* No error at all, this must be the HW reset value
2572 * Apparently no first measurement yet
2573 * Set MER to 0.0 */
2574 iMER = 0;
2575 } else {
2576 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03002577 EqRegTdSqrErrExp;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002578 if ((transmissionParams &
2579 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2580 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2581 tpsCnt = 17;
2582 else
2583 tpsCnt = 68;
2584
2585 /* IMER = 100 * log10 (x)
2586 where x = (EqRegTdTpsPwrOfs^2 *
2587 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2588
2589 => IMER = a + b -c
2590 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2591 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2592 c = 100 * log10 (SqrErrIQ)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002593 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002594
2595 /* log(x) x = 9bits * 9bits->18 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002596 a = Log10Times100(EqRegTdTpsPwrOfs *
2597 EqRegTdTpsPwrOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002598 /* log(x) x = 16bits * 7bits->23 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002599 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002600 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2601 c = Log10Times100(SqrErrIQ);
2602
2603 iMER = a + b;
2604 /* No negative MER, clip to zero */
2605 if (iMER > c)
2606 iMER -= c;
2607 else
2608 iMER = 0;
2609 }
2610 *pSignalToNoise = iMER;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002611 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002612
2613 return status;
2614}
2615
2616static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2617{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002618 dprintk(1, "\n");
2619
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002620 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002621 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002622 case OM_DVBT:
2623 return GetDVBTSignalToNoise(state, pSignalToNoise);
2624 case OM_QAM_ITU_A:
2625 case OM_QAM_ITU_C:
2626 return GetQAMSignalToNoise(state, pSignalToNoise);
2627 default:
2628 break;
2629 }
2630 return 0;
2631}
2632
2633#if 0
2634static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2635{
2636 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2637 int status = 0;
2638
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002639 dprintk(1, "\n");
2640
Oliver Endrissebc7de22011-07-03 13:49:44 -03002641 static s32 QE_SN[] = {
2642 51, /* QPSK 1/2 */
2643 69, /* QPSK 2/3 */
2644 79, /* QPSK 3/4 */
2645 89, /* QPSK 5/6 */
2646 97, /* QPSK 7/8 */
2647 108, /* 16-QAM 1/2 */
2648 131, /* 16-QAM 2/3 */
2649 146, /* 16-QAM 3/4 */
2650 156, /* 16-QAM 5/6 */
2651 160, /* 16-QAM 7/8 */
2652 165, /* 64-QAM 1/2 */
2653 187, /* 64-QAM 2/3 */
2654 202, /* 64-QAM 3/4 */
2655 216, /* 64-QAM 5/6 */
2656 225, /* 64-QAM 7/8 */
2657 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002658
2659 *pQuality = 0;
2660
2661 do {
2662 s32 SignalToNoise = 0;
2663 u16 Constellation = 0;
2664 u16 CodeRate = 0;
2665 u32 SignalToNoiseRel;
2666 u32 BERQuality;
2667
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002668 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2669 if (status < 0)
2670 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002671 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002672 if (status < 0)
2673 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002674 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2675
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002676 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002677 if (status < 0)
2678 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002679 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2680
2681 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2682 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2683 break;
2684 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002685 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002686 BERQuality = 100;
2687
Oliver Endrissebc7de22011-07-03 13:49:44 -03002688 if (SignalToNoiseRel < -70)
2689 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002690 else if (SignalToNoiseRel < 30)
2691 *pQuality = ((SignalToNoiseRel + 70) *
2692 BERQuality) / 100;
2693 else
2694 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002695 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002696 return 0;
2697};
2698
Oliver Endrissebc7de22011-07-03 13:49:44 -03002699static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002700{
2701 int status = 0;
2702 *pQuality = 0;
2703
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002704 dprintk(1, "\n");
2705
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002706 do {
2707 u32 SignalToNoise = 0;
2708 u32 BERQuality = 100;
2709 u32 SignalToNoiseRel = 0;
2710
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002711 status = GetQAMSignalToNoise(state, &SignalToNoise);
2712 if (status < 0)
2713 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002714
Oliver Endrissebc7de22011-07-03 13:49:44 -03002715 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002716 case QAM_16:
2717 SignalToNoiseRel = SignalToNoise - 200;
2718 break;
2719 case QAM_32:
2720 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002721 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002722 case QAM_64:
2723 SignalToNoiseRel = SignalToNoise - 260;
2724 break;
2725 case QAM_128:
2726 SignalToNoiseRel = SignalToNoise - 290;
2727 break;
2728 default:
2729 case QAM_256:
2730 SignalToNoiseRel = SignalToNoise - 320;
2731 break;
2732 }
2733
2734 if (SignalToNoiseRel < -70)
2735 *pQuality = 0;
2736 else if (SignalToNoiseRel < 30)
2737 *pQuality = ((SignalToNoiseRel + 70) *
2738 BERQuality) / 100;
2739 else
2740 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002741 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002742
2743 return status;
2744}
2745
2746static int GetQuality(struct drxk_state *state, s32 *pQuality)
2747{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002748 dprintk(1, "\n");
2749
Oliver Endrissebc7de22011-07-03 13:49:44 -03002750 switch (state->m_OperationMode) {
2751 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002752 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002753 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002754 return GetDVBCQuality(state, pQuality);
2755 default:
2756 break;
2757 }
2758
2759 return 0;
2760}
2761#endif
2762
2763/* Free data ram in SIO HI */
2764#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2765#define SIO_HI_RA_RAM_USR_END__A 0x420060
2766
2767#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2768#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2769#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2770#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2771
2772#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2773#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2774#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2775
2776static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2777{
2778 int status;
2779
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002780 dprintk(1, "\n");
2781
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002782 if (state->m_DrxkState == DRXK_UNINITIALIZED)
2783 return -1;
2784 if (state->m_DrxkState == DRXK_POWERED_DOWN)
2785 return -1;
2786
2787 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002788 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 -03002789 if (status < 0)
2790 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002791 if (bEnableBridge) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002792 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 -03002793 if (status < 0)
2794 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002795 } else {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002796 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 -03002797 if (status < 0)
2798 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002799 }
2800
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002801 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2802 if (status < 0)
2803 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002804 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002805 return status;
2806}
2807
Oliver Endrissebc7de22011-07-03 13:49:44 -03002808static int SetPreSaw(struct drxk_state *state,
2809 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002810{
2811 int status;
2812
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002813 dprintk(1, "\n");
2814
Oliver Endrissebc7de22011-07-03 13:49:44 -03002815 if ((pPreSawCfg == NULL)
2816 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002817 return -1;
2818
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002819 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002820 return status;
2821}
2822
2823static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002824 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002825{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002826 u16 blStatus = 0;
2827 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2828 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2829 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002830 unsigned long end;
2831
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002832 dprintk(1, "\n");
2833
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002834 mutex_lock(&state->mutex);
2835 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002836 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002837 if (status < 0)
2838 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002839 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002840 if (status < 0)
2841 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002842 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002843 if (status < 0)
2844 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002845 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002846 if (status < 0)
2847 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002848 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002849 if (status < 0)
2850 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002851 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002852 if (status < 0)
2853 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002854
Oliver Endrissebc7de22011-07-03 13:49:44 -03002855 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002856 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002857 status = read16(state, SIO_BL_STATUS__A, &blStatus);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002858 if (status < 0)
2859 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002860 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002861 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03002862 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002863 mutex_unlock(&state->mutex);
2864 return -1;
2865 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03002866 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002867 mutex_unlock(&state->mutex);
2868 return status;
2869
2870}
2871
Oliver Endrissebc7de22011-07-03 13:49:44 -03002872static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002873{
2874 u16 data = 0;
2875 int status;
2876
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002877 dprintk(1, "\n");
2878
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002879 do {
2880 /* Start measurement */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002881 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002882 if (status < 0)
2883 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002884 status = write16(state, IQM_AF_START_LOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002885 if (status < 0)
2886 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002887
2888 *count = 0;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002889 status = read16(state, IQM_AF_PHASE0__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002890 if (status < 0)
2891 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002892 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002893 *count = *count + 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002894 status = read16(state, IQM_AF_PHASE1__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002895 if (status < 0)
2896 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002897 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002898 *count = *count + 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002899 status = read16(state, IQM_AF_PHASE2__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002900 if (status < 0)
2901 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002902 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002903 *count = *count + 1;
2904 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002905 return status;
2906}
2907
2908static int ADCSynchronization(struct drxk_state *state)
2909{
2910 u16 count = 0;
2911 int status;
2912
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002913 dprintk(1, "\n");
2914
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002915 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002916 status = ADCSyncMeasurement(state, &count);
2917 if (status < 0)
2918 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002919
Oliver Endrissebc7de22011-07-03 13:49:44 -03002920 if (count == 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002921 /* Try sampling on a diffrent edge */
2922 u16 clkNeg = 0;
2923
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002924 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002925 if (status < 0)
2926 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002927 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002928 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2929 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2930 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002931 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002932 } else {
2933 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2934 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002935 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002936 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002937 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002938 if (status < 0)
2939 break;
2940 status = ADCSyncMeasurement(state, &count);
2941 if (status < 0)
2942 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002943 }
2944
2945 if (count < 2)
2946 status = -1;
2947 } while (0);
2948 return status;
2949}
2950
2951static int SetFrequencyShifter(struct drxk_state *state,
2952 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002953 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002954{
2955 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002956 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002957 u32 fmFrequencyShift = 0;
2958 bool tunerMirror = !state->m_bMirrorFreqSpect;
2959 u32 adcFreq;
2960 bool adcFlip;
2961 int status;
2962 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002963 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002964 u32 frequencyShift;
2965 bool imageToSelect;
2966
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002967 dprintk(1, "\n");
2968
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002969 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03002970 Program frequency shifter
2971 No need to account for mirroring on RF
2972 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002973 if (isDTV) {
2974 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
2975 (state->m_OperationMode == OM_QAM_ITU_C) ||
2976 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03002977 selectPosImage = true;
2978 else
2979 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002980 }
2981 if (tunerMirror)
2982 /* tuner doesn't mirror */
2983 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03002984 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002985 else
2986 /* tuner mirrors */
2987 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002988 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002989 if (ifFreqActual > samplingFrequency / 2) {
2990 /* adc mirrors */
2991 adcFreq = samplingFrequency - ifFreqActual;
2992 adcFlip = true;
2993 } else {
2994 /* adc doesn't mirror */
2995 adcFreq = ifFreqActual;
2996 adcFlip = false;
2997 }
2998
2999 frequencyShift = adcFreq;
3000 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003001 adcFlip ^ selectPosImage;
3002 state->m_IqmFsRateOfs =
3003 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003004
3005 if (imageToSelect)
3006 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3007
3008 /* Program frequency shifter with tuner offset compensation */
3009 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003010 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3011 state->m_IqmFsRateOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003012 return status;
3013}
3014
3015static int InitAGC(struct drxk_state *state, bool isDTV)
3016{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003017 u16 ingainTgt = 0;
3018 u16 ingainTgtMin = 0;
3019 u16 ingainTgtMax = 0;
3020 u16 clpCyclen = 0;
3021 u16 clpSumMin = 0;
3022 u16 clpDirTo = 0;
3023 u16 snsSumMin = 0;
3024 u16 snsSumMax = 0;
3025 u16 clpSumMax = 0;
3026 u16 snsDirTo = 0;
3027 u16 kiInnergainMin = 0;
3028 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003029 u16 ifIaccuHiTgtMin = 0;
3030 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003031 u16 data = 0;
3032 u16 fastClpCtrlDelay = 0;
3033 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003034 int status = 0;
3035
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003036 dprintk(1, "\n");
3037
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003038 do {
3039 /* Common settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003040 snsSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003041 ifIaccuHiTgtMin = 2047;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003042 clpCyclen = 500;
3043 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003044
3045 if (IsQAM(state)) {
3046 /* Standard specific settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003047 clpSumMin = 8;
3048 clpDirTo = (u16) -9;
3049 clpCtrlMode = 0;
3050 snsSumMin = 8;
3051 snsDirTo = (u16) -9;
3052 kiInnergainMin = (u16) -1030;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003053 } else
3054 status = -1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003055 status = (status);
3056 if (status < 0)
3057 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003058 if (IsQAM(state)) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003059 ifIaccuHiTgtMax = 0x2380;
3060 ifIaccuHiTgt = 0x2380;
3061 ingainTgtMin = 0x0511;
3062 ingainTgt = 0x0511;
3063 ingainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003064 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003065 state->m_qamIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003066 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003067 ifIaccuHiTgtMax = 0x1200;
3068 ifIaccuHiTgt = 0x1200;
3069 ingainTgtMin = 13424;
3070 ingainTgt = 13424;
3071 ingainTgtMax = 30000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003072 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003073 state->m_dvbtIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003074 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003075 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003076 if (status < 0)
3077 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003078
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003079 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003080 if (status < 0)
3081 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003082 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003083 if (status < 0)
3084 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003085 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003086 if (status < 0)
3087 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003088 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003089 if (status < 0)
3090 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003091 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003092 if (status < 0)
3093 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003094 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003095 if (status < 0)
3096 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003097 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003098 if (status < 0)
3099 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003100 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003101 if (status < 0)
3102 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003103 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003104 if (status < 0)
3105 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003106 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003107 if (status < 0)
3108 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003109 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003110 if (status < 0)
3111 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003112 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003113 if (status < 0)
3114 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003115
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003116 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003117 if (status < 0)
3118 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003119 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003120 if (status < 0)
3121 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003122 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003123 if (status < 0)
3124 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003125
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003126 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003127 if (status < 0)
3128 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003129 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003130 if (status < 0)
3131 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003132 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003133 if (status < 0)
3134 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003135
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003136 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003137 if (status < 0)
3138 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003139 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003140 if (status < 0)
3141 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003142 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003143 if (status < 0)
3144 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003145 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003146 if (status < 0)
3147 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003148 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003149 if (status < 0)
3150 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003151 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003152 if (status < 0)
3153 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003154 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003155 if (status < 0)
3156 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003157 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003158 if (status < 0)
3159 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003160 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003161 if (status < 0)
3162 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003163 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003164 if (status < 0)
3165 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003166 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003167 if (status < 0)
3168 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003169 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003170 if (status < 0)
3171 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003172 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003173 if (status < 0)
3174 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003175 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003176 if (status < 0)
3177 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003178 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003179 if (status < 0)
3180 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003181 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003182 if (status < 0)
3183 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003184 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003185 if (status < 0)
3186 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003187 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003188 if (status < 0)
3189 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003190 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003191 if (status < 0)
3192 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003193
3194 /* Initialize inner-loop KI gain factors */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003195 status = read16(state, SCU_RAM_AGC_KI__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003196 if (status < 0)
3197 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003198 if (IsQAM(state)) {
3199 data = 0x0657;
3200 data &= ~SCU_RAM_AGC_KI_RF__M;
3201 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3202 data &= ~SCU_RAM_AGC_KI_IF__M;
3203 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3204 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003205 status = write16(state, SCU_RAM_AGC_KI__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003206 if (status < 0)
3207 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003208 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003209 return status;
3210}
3211
Oliver Endrissebc7de22011-07-03 13:49:44 -03003212static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003213{
3214 int status;
3215
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003216 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003217 do {
3218 if (packetErr == NULL) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003219 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003220 if (status < 0)
3221 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003222 } else {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003223 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003224 if (status < 0)
3225 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003226 }
3227 } while (0);
3228 return status;
3229}
3230
3231static int DVBTScCommand(struct drxk_state *state,
3232 u16 cmd, u16 subcmd,
3233 u16 param0, u16 param1, u16 param2,
3234 u16 param3, u16 param4)
3235{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003236 u16 curCmd = 0;
3237 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003238 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003239 u16 scExec = 0;
3240 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003241
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003242 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003243 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003244 if (scExec != 1) {
3245 /* SC is not running */
3246 return -1;
3247 }
3248
3249 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003250 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003251 do {
3252 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003253 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003254 retryCnt++;
3255 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
3256 if (retryCnt >= DRXK_MAX_RETRIES)
3257 return -1;
3258 /* Write sub-command */
3259 switch (cmd) {
3260 /* All commands using sub-cmd */
3261 case OFDM_SC_RA_RAM_CMD_PROC_START:
3262 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3263 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003264 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003265 write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003266 break;
3267 default:
3268 /* Do nothing */
3269 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003270 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003271
3272 /* Write needed parameters and the command */
3273 switch (cmd) {
3274 /* All commands using 5 parameters */
3275 /* All commands using 4 parameters */
3276 /* All commands using 3 parameters */
3277 /* All commands using 2 parameters */
3278 case OFDM_SC_RA_RAM_CMD_PROC_START:
3279 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3280 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003281 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003282 write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003283 /* All commands using 1 parameters */
3284 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3285 case OFDM_SC_RA_RAM_CMD_USER_IO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003286 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003287 write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003288 /* All commands using 0 parameters */
3289 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3290 case OFDM_SC_RA_RAM_CMD_NULL:
3291 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003292 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003293 break;
3294 default:
3295 /* Unknown command */
3296 return -EINVAL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003297 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003298
3299 /* Wait until sc is ready processing command */
3300 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003301 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003302 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003303 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003304 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003305 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003306 if (retryCnt >= DRXK_MAX_RETRIES)
3307 return -1;
3308
3309 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003310 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003311 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003312 /* illegal command */
3313 return -EINVAL;
3314 }
3315
3316 /* Retreive results parameters from SC */
3317 switch (cmd) {
3318 /* All commands yielding 5 results */
3319 /* All commands yielding 4 results */
3320 /* All commands yielding 3 results */
3321 /* All commands yielding 2 results */
3322 /* All commands yielding 1 result */
3323 case OFDM_SC_RA_RAM_CMD_USER_IO:
3324 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003325 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003326 read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003327 /* All commands yielding 0 results */
3328 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3329 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3330 case OFDM_SC_RA_RAM_CMD_PROC_START:
3331 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3332 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3333 case OFDM_SC_RA_RAM_CMD_NULL:
3334 break;
3335 default:
3336 /* Unknown command */
3337 return -EINVAL;
3338 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003339 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003340 return status;
3341}
3342
Oliver Endrissebc7de22011-07-03 13:49:44 -03003343static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003344{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003345 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003346 int status;
3347
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003348 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003349 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003350 status = CtrlPowerMode(state, &powerMode);
3351 if (status < 0)
3352 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003353 } while (0);
3354 return status;
3355}
3356
Oliver Endrissebc7de22011-07-03 13:49:44 -03003357static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003358{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003359 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003360
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003361 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003362 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003363 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003364 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003365 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003366
3367 return status;
3368}
3369
3370#define DEFAULT_FR_THRES_8K 4000
3371static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3372{
3373
3374 int status;
3375
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003376 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003377 if (*enabled == true) {
3378 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003379 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003380 DEFAULT_FR_THRES_8K);
3381 } else {
3382 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003383 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003384 }
3385
3386 return status;
3387}
3388
3389static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3390 struct DRXKCfgDvbtEchoThres_t *echoThres)
3391{
3392 u16 data = 0;
3393 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003394
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003395 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003396 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003397 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003398 if (status < 0)
3399 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003400
Oliver Endrissebc7de22011-07-03 13:49:44 -03003401 switch (echoThres->fftMode) {
3402 case DRX_FFTMODE_2K:
3403 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3404 data |=
3405 ((echoThres->threshold <<
3406 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3407 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3408 break;
3409 case DRX_FFTMODE_8K:
3410 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3411 data |=
3412 ((echoThres->threshold <<
3413 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3414 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3415 break;
3416 default:
3417 return -1;
3418 break;
3419 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003420
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003421 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003422 if (status < 0)
3423 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003424 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003425
Oliver Endrissebc7de22011-07-03 13:49:44 -03003426 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003427}
3428
3429static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003430 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003431{
3432 int status;
3433
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003434 dprintk(1, "\n");
3435
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003436 switch (*speed) {
3437 case DRXK_DVBT_SQI_SPEED_FAST:
3438 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3439 case DRXK_DVBT_SQI_SPEED_SLOW:
3440 break;
3441 default:
3442 return -EINVAL;
3443 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003444 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003445 (u16) *speed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003446 return status;
3447}
3448
3449/*============================================================================*/
3450
3451/**
3452* \brief Activate DVBT specific presets
3453* \param demod instance of demodulator.
3454* \return DRXStatus_t.
3455*
3456* Called in DVBTSetStandard
3457*
3458*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003459static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003460{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003461 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003462
Oliver Endrissebc7de22011-07-03 13:49:44 -03003463 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3464 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003465
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003466 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003467 do {
3468 bool setincenable = false;
3469 bool setfrenable = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003470 status = DVBTCtrlSetIncEnable(state, &setincenable);
3471 if (status < 0)
3472 break;
3473 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3474 if (status < 0)
3475 break;
3476 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3477 if (status < 0)
3478 break;
3479 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3480 if (status < 0)
3481 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003482 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003483 if (status < 0)
3484 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003485 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003486
Oliver Endrissebc7de22011-07-03 13:49:44 -03003487 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003488}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003489
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003490/*============================================================================*/
3491
3492/**
3493* \brief Initialize channelswitch-independent settings for DVBT.
3494* \param demod instance of demodulator.
3495* \return DRXStatus_t.
3496*
3497* For ROM code channel filter taps are loaded from the bootloader. For microcode
3498* the DVB-T taps from the drxk_filters.h are used.
3499*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003500static int SetDVBTStandard(struct drxk_state *state,
3501 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003502{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003503 u16 cmdResult = 0;
3504 u16 data = 0;
3505 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003506
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003507 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003508
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003509 PowerUpDVBT(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003510 do {
3511 /* added antenna switch */
3512 SwitchAntennaToDVBT(state);
3513 /* send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003514 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
3515 if (status < 0)
3516 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003517
3518 /* send OFDM setenv command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003519 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3520 if (status < 0)
3521 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003522
3523 /* reset datapath for OFDM, processors first */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003524 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003525 if (status < 0)
3526 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003527 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003528 if (status < 0)
3529 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003530 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003531 if (status < 0)
3532 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003533
3534 /* IQM setup */
3535 /* synchronize on ofdstate->m_festart */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003536 status = write16(state, IQM_AF_UPD_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003537 if (status < 0)
3538 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003539 /* window size for clipping ADC detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003540 status = write16(state, IQM_AF_CLP_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003541 if (status < 0)
3542 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003543 /* window size for for sense pre-SAW detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003544 status = write16(state, IQM_AF_SNS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003545 if (status < 0)
3546 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003547 /* sense threshold for sense pre-SAW detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003548 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003549 if (status < 0)
3550 break;
3551 status = SetIqmAf(state, true);
3552 if (status < 0)
3553 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003554
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003555 status = write16(state, IQM_AF_AGC_RF__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003556 if (status < 0)
3557 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003558
3559 /* Impulse noise cruncher setup */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003560 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003561 if (status < 0)
3562 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003563 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003564 if (status < 0)
3565 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003566 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003567 if (status < 0)
3568 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003569
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003570 status = write16(state, IQM_RC_STRETCH__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003571 if (status < 0)
3572 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003573 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003574 if (status < 0)
3575 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003576 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003577 if (status < 0)
3578 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003579 status = write16(state, IQM_CF_SCALE__A, 1600);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003580 if (status < 0)
3581 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003582 status = write16(state, IQM_CF_SCALE_SH__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003583 if (status < 0)
3584 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003585
3586 /* virtual clipping threshold for clipping ADC detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003587 status = write16(state, IQM_AF_CLP_TH__A, 448);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003588 if (status < 0)
3589 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003590 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003591 if (status < 0)
3592 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003593
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003594 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3595 if (status < 0)
3596 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003597
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003598 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003599 if (status < 0)
3600 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003601 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003602 if (status < 0)
3603 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003604 /* enable power measurement interrupt */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003605 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003606 if (status < 0)
3607 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003608 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003609 if (status < 0)
3610 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003611
3612 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003613 status = ADCSynchronization(state);
3614 if (status < 0)
3615 break;
3616 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3617 if (status < 0)
3618 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003619
3620 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003621 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003622 if (status < 0)
3623 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003624
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003625 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3626 if (status < 0)
3627 break;
3628 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3629 if (status < 0)
3630 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003631
3632 /* Set Noise Estimation notch width and enable DC fix */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003633 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003634 if (status < 0)
3635 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003636 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003637 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003638 if (status < 0)
3639 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003640
3641 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003642 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003643 if (status < 0)
3644 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003645
Oliver Endrissebc7de22011-07-03 13:49:44 -03003646 if (!state->m_DRXK_A3_ROM_CODE) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003647 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003648 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003649 if (status < 0)
3650 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003651 }
3652
3653 /* OFDM_SC setup */
3654#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003655 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003656 if (status < 0)
3657 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003658 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003659 if (status < 0)
3660 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003661#endif
3662
3663 /* FEC setup */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003664 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003665 if (status < 0)
3666 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003667
3668
3669#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003670 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003671 if (status < 0)
3672 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003673#else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003674 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003675 if (status < 0)
3676 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003677#endif
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003678 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003679 if (status < 0)
3680 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003681
3682 /* Setup MPEG bus */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003683 status = MPEGTSDtoSetup(state, OM_DVBT);
3684 if (status < 0)
3685 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003686 /* Set DVBT Presets */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003687 status = DVBTActivatePresets(state);
3688 if (status < 0)
3689 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003690
3691 } while (0);
3692
Oliver Endrissebc7de22011-07-03 13:49:44 -03003693 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003694 printk(KERN_ERR "drxk: %s status - %08x\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003695
3696 return status;
3697}
3698
3699/*============================================================================*/
3700/**
3701* \brief Start dvbt demodulating for channel.
3702* \param demod instance of demodulator.
3703* \return DRXStatus_t.
3704*/
3705static int DVBTStart(struct drxk_state *state)
3706{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003707 u16 param1;
3708 int status;
3709 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003710
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003711 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003712 /* Start correct processes to get in lock */
3713 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
3714 do {
3715 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003716 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3717 if (status < 0)
3718 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003719 /* Start FEC OC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003720 status = MPEGTSStart(state);
3721 if (status < 0)
3722 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003723 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003724 if (status < 0)
3725 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003726 } while (0);
3727 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003728}
3729
3730
3731/*============================================================================*/
3732
3733/**
3734* \brief Set up dvbt demodulator for channel.
3735* \param demod instance of demodulator.
3736* \return DRXStatus_t.
3737* // original DVBTSetChannel()
3738*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003739static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3740 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003741{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003742 u16 cmdResult = 0;
3743 u16 transmissionParams = 0;
3744 u16 operationMode = 0;
3745 u32 iqmRcRateOfs = 0;
3746 u32 bandwidth = 0;
3747 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003748 int status;
3749
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003750 dprintk(1, "\n");
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003751 /* printk(KERN_DEBUG "drxk: %s IF =%d, TFO = %d\n", __func__, IntermediateFreqkHz, tunerFreqOffset); */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003752 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003753 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3754 if (status < 0)
3755 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003756
3757 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003758 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003759 if (status < 0)
3760 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003761
3762 /* Stop processors */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003763 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003764 if (status < 0)
3765 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003766 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003767 if (status < 0)
3768 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003769
3770 /* Mandatory fix, always stop CP, required to set spl offset back to
3771 hardware default (is set to 0 by ucode during pilot detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003772 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003773 if (status < 0)
3774 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003775
3776 /*== Write channel settings to device =====================================*/
3777
3778 /* mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003779 switch (state->param.u.ofdm.transmission_mode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003780 case TRANSMISSION_MODE_AUTO:
3781 default:
3782 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3783 /* fall through , try first guess DRX_FFTMODE_8K */
3784 case TRANSMISSION_MODE_8K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003785 transmissionParams |=
3786 OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003787 break;
3788 case TRANSMISSION_MODE_2K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003789 transmissionParams |=
3790 OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003791 break;
3792 }
3793
3794 /* guard */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003795 switch (state->param.u.ofdm.guard_interval) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003796 default:
3797 case GUARD_INTERVAL_AUTO:
3798 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3799 /* fall through , try first guess DRX_GUARD_1DIV4 */
3800 case GUARD_INTERVAL_1_4:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003801 transmissionParams |=
3802 OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003803 break;
3804 case GUARD_INTERVAL_1_32:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003805 transmissionParams |=
3806 OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003807 break;
3808 case GUARD_INTERVAL_1_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003809 transmissionParams |=
3810 OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003811 break;
3812 case GUARD_INTERVAL_1_8:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003813 transmissionParams |=
3814 OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003815 break;
3816 }
3817
3818 /* hierarchy */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003819 switch (state->param.u.ofdm.hierarchy_information) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003820 case HIERARCHY_AUTO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003821 case HIERARCHY_NONE:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003822 default:
3823 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3824 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003825 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3826 /* break; */
3827 case HIERARCHY_1:
3828 transmissionParams |=
3829 OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003830 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003831 case HIERARCHY_2:
3832 transmissionParams |=
3833 OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003834 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003835 case HIERARCHY_4:
3836 transmissionParams |=
3837 OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003838 break;
3839 }
3840
3841
3842 /* constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003843 switch (state->param.u.ofdm.constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003844 case QAM_AUTO:
3845 default:
3846 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3847 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3848 case QAM_64:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003849 transmissionParams |=
3850 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003851 break;
3852 case QPSK:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003853 transmissionParams |=
3854 OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003855 break;
3856 case QAM_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003857 transmissionParams |=
3858 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003859 break;
3860 }
3861#if 0
Oliver Endrissebc7de22011-07-03 13:49:44 -03003862 /* No hierachical channels support in BDA */
3863 /* Priority (only for hierarchical channels) */
3864 switch (channel->priority) {
3865 case DRX_PRIORITY_LOW:
3866 transmissionParams |=
3867 OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3868 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3869 OFDM_EC_SB_PRIOR_LO);
3870 break;
3871 case DRX_PRIORITY_HIGH:
3872 transmissionParams |=
3873 OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3874 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3875 OFDM_EC_SB_PRIOR_HI));
3876 break;
3877 case DRX_PRIORITY_UNKNOWN: /* fall through */
3878 default:
3879 return DRX_STS_INVALID_ARG;
3880 break;
3881 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003882#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03003883 /* Set Priorty high */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003884 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003885 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003886 if (status < 0)
3887 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003888#endif
3889
3890 /* coderate */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003891 switch (state->param.u.ofdm.code_rate_HP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003892 case FEC_AUTO:
3893 default:
3894 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3895 /* fall through , try first guess DRX_CODERATE_2DIV3 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003896 case FEC_2_3:
3897 transmissionParams |=
3898 OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003899 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003900 case FEC_1_2:
3901 transmissionParams |=
3902 OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003903 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003904 case FEC_3_4:
3905 transmissionParams |=
3906 OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003907 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003908 case FEC_5_6:
3909 transmissionParams |=
3910 OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003911 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003912 case FEC_7_8:
3913 transmissionParams |=
3914 OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003915 break;
3916 }
3917
3918 /* SAW filter selection: normaly not necesarry, but if wanted
3919 the application can select a SAW filter via the driver by using UIOs */
3920 /* First determine real bandwidth (Hz) */
3921 /* Also set delay for impulse noise cruncher */
3922 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3923 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3924 functions */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003925 switch (state->param.u.ofdm.bandwidth) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003926 case BANDWIDTH_AUTO:
3927 case BANDWIDTH_8_MHZ:
3928 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003929 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003930 if (status < 0)
3931 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003932 /* cochannel protection for PAL 8 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003933 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003934 if (status < 0)
3935 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003936 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003937 if (status < 0)
3938 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003939 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003940 if (status < 0)
3941 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003942 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003943 if (status < 0)
3944 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003945 break;
3946 case BANDWIDTH_7_MHZ:
3947 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003948 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003949 if (status < 0)
3950 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003951 /* cochannel protection for PAL 7 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003952 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003953 if (status < 0)
3954 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003955 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003956 if (status < 0)
3957 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003958 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003959 if (status < 0)
3960 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003961 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003962 if (status < 0)
3963 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003964 break;
3965 case BANDWIDTH_6_MHZ:
3966 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003967 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003968 if (status < 0)
3969 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003970 /* cochannel protection for NTSC 6 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003971 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003972 if (status < 0)
3973 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003974 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003975 if (status < 0)
3976 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003977 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003978 if (status < 0)
3979 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003980 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003981 if (status < 0)
3982 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003983 break;
Mauro Carvalho Chehabe16cede2011-07-03 18:18:14 -03003984 default:
3985 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003986 }
3987
Oliver Endrissebc7de22011-07-03 13:49:44 -03003988 if (iqmRcRateOfs == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003989 /* Now compute IQM_RC_RATE_OFS
3990 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3991 =>
3992 ((SysFreq / BandWidth) * (2^21)) - (2^23)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003993 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003994 /* (SysFreq / BandWidth) * (2^28) */
3995 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
3996 => assert(MAX(sysClk) < 16*MIN(bandwidth))
3997 => assert(109714272 > 48000000) = true so Frac 28 can be used */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003998 iqmRcRateOfs = Frac28a((u32)
3999 ((state->m_sysClockFreq *
4000 1000) / 3), bandwidth);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004001 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4002 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004003 iqmRcRateOfs += 0x80L;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004004 iqmRcRateOfs = iqmRcRateOfs >> 7;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004005 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004006 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004007 }
4008
Oliver Endrissebc7de22011-07-03 13:49:44 -03004009 iqmRcRateOfs &=
4010 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4011 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004012 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004013 if (status < 0)
4014 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004015
4016 /* Bandwidth setting done */
4017
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004018#if 0
4019 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4020 if (status < 0)
4021 break;
4022#endif
4023 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4024 if (status < 0)
4025 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004026
4027 /*== Start SC, write channel settings to SC ===============================*/
4028
4029 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004030 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004031 if (status < 0)
4032 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004033
4034 /* Enable SC after setting all other parameters */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004035 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004036 if (status < 0)
4037 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004038 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004039 if (status < 0)
4040 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004041
4042
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004043 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4044 if (status < 0)
4045 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004046
4047 /* Write SC parameter registers, set all AUTO flags in operation mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004048 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4049 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4050 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4051 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4052 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4053 status =
4054 DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4055 0, transmissionParams, param1, 0, 0, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004056 if (!state->m_DRXK_A3_ROM_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004057 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4058 if (status < 0)
4059 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004060
Oliver Endrissebc7de22011-07-03 13:49:44 -03004061 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004062
4063 return status;
4064}
4065
4066
4067/*============================================================================*/
4068
4069/**
4070* \brief Retreive lock status .
4071* \param demod Pointer to demodulator instance.
4072* \param lockStat Pointer to lock status structure.
4073* \return DRXStatus_t.
4074*
4075*/
4076static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4077{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004078 int status;
4079 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4080 OFDM_SC_RA_RAM_LOCK_FEC__M);
4081 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4082 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004083
Oliver Endrissebc7de22011-07-03 13:49:44 -03004084 u16 ScRaRamLock = 0;
4085 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004086
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004087 dprintk(1, "\n");
4088
Oliver Endrissebc7de22011-07-03 13:49:44 -03004089 /* driver 0.9.0 */
4090 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004091 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004092 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP) {
4093 /* SC not active; return DRX_NOT_LOCKED */
4094 *pLockStatus = NOT_LOCKED;
4095 return status;
4096 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004097
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004098 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004099
Oliver Endrissebc7de22011-07-03 13:49:44 -03004100 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4101 *pLockStatus = MPEG_LOCK;
4102 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4103 *pLockStatus = FEC_LOCK;
4104 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4105 *pLockStatus = DEMOD_LOCK;
4106 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4107 *pLockStatus = NEVER_LOCK;
4108 else
4109 *pLockStatus = NOT_LOCKED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004110
Oliver Endrissebc7de22011-07-03 13:49:44 -03004111 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004112}
4113
Oliver Endrissebc7de22011-07-03 13:49:44 -03004114static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004115{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004116 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
4117 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004118
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004119 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004120 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004121 status = CtrlPowerMode(state, &powerMode);
4122 if (status < 0)
4123 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004124
Oliver Endrissebc7de22011-07-03 13:49:44 -03004125 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004126
Oliver Endrissebc7de22011-07-03 13:49:44 -03004127 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004128}
4129
4130
Oliver Endrissebc7de22011-07-03 13:49:44 -03004131/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004132static int PowerDownQAM(struct drxk_state *state)
4133{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004134 u16 data = 0;
4135 u16 cmdResult;
4136 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004137
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004138 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004139 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004140 status = read16(state, SCU_COMM_EXEC__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004141 if (status < 0)
4142 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004143 if (data == SCU_COMM_EXEC_ACTIVE) {
4144 /*
4145 STOP demodulator
4146 QAM and HW blocks
4147 */
4148 /* stop all comstate->m_exec */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004149 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004150 if (status < 0)
4151 break;
4152 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
4153 if (status < 0)
4154 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004155 }
4156 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004157 status = SetIqmAf(state, false);
4158 if (status < 0)
4159 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004160 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004161
Oliver Endrissebc7de22011-07-03 13:49:44 -03004162 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004163}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004164
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004165/*============================================================================*/
4166
4167/**
4168* \brief Setup of the QAM Measurement intervals for signal quality
4169* \param demod instance of demod.
4170* \param constellation current constellation.
4171* \return DRXStatus_t.
4172*
4173* NOTE:
4174* Take into account that for certain settings the errorcounters can overflow.
4175* The implementation does not check this.
4176*
4177*/
4178static int SetQAMMeasurement(struct drxk_state *state,
4179 enum EDrxkConstellation constellation,
4180 u32 symbolRate)
4181{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004182 u32 fecBitsDesired = 0; /* BER accounting period */
4183 u32 fecRsPeriodTotal = 0; /* Total period */
4184 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4185 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004186 int status = 0;
4187
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004188 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004189
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004190 fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004191 do {
4192
4193 /* fecBitsDesired = symbolRate [kHz] *
4194 FrameLenght [ms] *
4195 (constellation + 1) *
4196 SyncLoss (== 1) *
4197 ViterbiLoss (==1)
Oliver Endrissebc7de22011-07-03 13:49:44 -03004198 */
4199 switch (constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004200 case DRX_CONSTELLATION_QAM16:
4201 fecBitsDesired = 4 * symbolRate;
4202 break;
4203 case DRX_CONSTELLATION_QAM32:
4204 fecBitsDesired = 5 * symbolRate;
4205 break;
4206 case DRX_CONSTELLATION_QAM64:
4207 fecBitsDesired = 6 * symbolRate;
4208 break;
4209 case DRX_CONSTELLATION_QAM128:
4210 fecBitsDesired = 7 * symbolRate;
4211 break;
4212 case DRX_CONSTELLATION_QAM256:
4213 fecBitsDesired = 8 * symbolRate;
4214 break;
4215 default:
4216 status = -EINVAL;
4217 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004218 status = status;
4219 if (status < 0)
4220 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004221
Oliver Endrissebc7de22011-07-03 13:49:44 -03004222 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4223 fecBitsDesired *= 500; /* meas. period [ms] */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004224
4225 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4226 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004227 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004228
4229 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4230 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4231 if (fecRsPrescale == 0) {
4232 /* Divide by zero (though impossible) */
4233 status = -1;
4234 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004235 status = status;
4236 if (status < 0)
4237 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004238 fecRsPeriod =
4239 ((u16) fecRsPeriodTotal +
4240 (fecRsPrescale >> 1)) / fecRsPrescale;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004241
4242 /* write corresponding registers */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004243 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004244 if (status < 0)
4245 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004246 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004247 if (status < 0)
4248 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004249 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004250 if (status < 0)
4251 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004252
4253 } while (0);
4254
Oliver Endrissebc7de22011-07-03 13:49:44 -03004255 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03004256 printk(KERN_ERR "drxk: %s: status - %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004257
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004258 return status;
4259}
4260
Oliver Endrissebc7de22011-07-03 13:49:44 -03004261static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004262{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004263 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004264
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004265 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004266 do {
4267 /* QAM Equalizer Setup */
4268 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004269 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004270 if (status < 0)
4271 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004272 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004273 if (status < 0)
4274 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004275 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004276 if (status < 0)
4277 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004278 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004279 if (status < 0)
4280 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004281 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004282 if (status < 0)
4283 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004284 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004285 if (status < 0)
4286 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004287 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004288 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004289 if (status < 0)
4290 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004291 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004292 if (status < 0)
4293 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004294 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004295 if (status < 0)
4296 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004297 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004298 if (status < 0)
4299 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004300 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004301 if (status < 0)
4302 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004303 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004304 if (status < 0)
4305 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004306
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004307 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004308 if (status < 0)
4309 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004310 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004311 if (status < 0)
4312 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004313 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004314 if (status < 0)
4315 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004316
Oliver Endrissebc7de22011-07-03 13:49:44 -03004317 /* QAM Slicer Settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004318 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004319 if (status < 0)
4320 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004321
Oliver Endrissebc7de22011-07-03 13:49:44 -03004322 /* QAM Loop Controller Coeficients */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004323 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004324 if (status < 0)
4325 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004326 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004327 if (status < 0)
4328 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004329 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004330 if (status < 0)
4331 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004332 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004333 if (status < 0)
4334 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004335 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004336 if (status < 0)
4337 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004338 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004339 if (status < 0)
4340 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004341 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004342 if (status < 0)
4343 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004344 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004345 if (status < 0)
4346 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004347
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004348 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004349 if (status < 0)
4350 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004351 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004352 if (status < 0)
4353 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004354 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004355 if (status < 0)
4356 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004357 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004358 if (status < 0)
4359 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004360 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004361 if (status < 0)
4362 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004363 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004364 if (status < 0)
4365 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004366 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004367 if (status < 0)
4368 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004369 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004370 if (status < 0)
4371 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004372 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004373 if (status < 0)
4374 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004375 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004376 if (status < 0)
4377 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004378 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004379 if (status < 0)
4380 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004381 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004382 if (status < 0)
4383 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004384
4385
Oliver Endrissebc7de22011-07-03 13:49:44 -03004386 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004387
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004388 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004389 if (status < 0)
4390 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004391 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004392 if (status < 0)
4393 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004394 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004395 if (status < 0)
4396 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004397 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004398 if (status < 0)
4399 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004400 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004401 if (status < 0)
4402 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004403 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004404 if (status < 0)
4405 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004406
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004407 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004408 if (status < 0)
4409 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004410 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004411 if (status < 0)
4412 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004413 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004414 if (status < 0)
4415 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004416
4417
Oliver Endrissebc7de22011-07-03 13:49:44 -03004418 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004419
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004420 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004421 if (status < 0)
4422 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004423 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004424 if (status < 0)
4425 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004426 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004427 if (status < 0)
4428 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004429 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004430 if (status < 0)
4431 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004432 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004433 if (status < 0)
4434 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004435 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004436 if (status < 0)
4437 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004438 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004439 if (status < 0)
4440 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004441 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004442
Oliver Endrissebc7de22011-07-03 13:49:44 -03004443 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004444}
4445
4446/*============================================================================*/
4447
4448/**
4449* \brief QAM32 specific setup
4450* \param demod instance of demod.
4451* \return DRXStatus_t.
4452*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004453static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004454{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004455 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004456
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004457 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004458 do {
4459 /* QAM Equalizer Setup */
4460 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004461 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004462 if (status < 0)
4463 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004464 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004465 if (status < 0)
4466 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004467 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004468 if (status < 0)
4469 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004470 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004471 if (status < 0)
4472 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004473 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004474 if (status < 0)
4475 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004476 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004477 if (status < 0)
4478 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004479
Oliver Endrissebc7de22011-07-03 13:49:44 -03004480 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004481 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004482 if (status < 0)
4483 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004484 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004485 if (status < 0)
4486 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004487 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004488 if (status < 0)
4489 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004490 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004491 if (status < 0)
4492 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004493 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004494 if (status < 0)
4495 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004496 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004497 if (status < 0)
4498 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004499
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004500 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004501 if (status < 0)
4502 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004503 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004504 if (status < 0)
4505 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004506 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004507 if (status < 0)
4508 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004509
Oliver Endrissebc7de22011-07-03 13:49:44 -03004510 /* QAM Slicer Settings */
4511
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004512 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004513 if (status < 0)
4514 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004515
4516
Oliver Endrissebc7de22011-07-03 13:49:44 -03004517 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004518
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004519 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004520 if (status < 0)
4521 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004522 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004523 if (status < 0)
4524 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004525 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004526 if (status < 0)
4527 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004528 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004529 if (status < 0)
4530 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004531 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004532 if (status < 0)
4533 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004534 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004535 if (status < 0)
4536 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004537 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004538 if (status < 0)
4539 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004540 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004541 if (status < 0)
4542 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004543
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004544 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004545 if (status < 0)
4546 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004547 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004548 if (status < 0)
4549 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004550 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004551 if (status < 0)
4552 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004553 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004554 if (status < 0)
4555 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004556 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004557 if (status < 0)
4558 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004559 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004560 if (status < 0)
4561 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004562 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004563 if (status < 0)
4564 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004565 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004566 if (status < 0)
4567 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004568 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004569 if (status < 0)
4570 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004571 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004572 if (status < 0)
4573 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004574 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004575 if (status < 0)
4576 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004577 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004578 if (status < 0)
4579 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004580
4581
Oliver Endrissebc7de22011-07-03 13:49:44 -03004582 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004583
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004584 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004585 if (status < 0)
4586 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004587 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004588 if (status < 0)
4589 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004590 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004591 if (status < 0)
4592 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004593 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004594 if (status < 0)
4595 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004596 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004597 if (status < 0)
4598 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004599 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004600 if (status < 0)
4601 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004602
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004603 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004604 if (status < 0)
4605 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004606 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004607 if (status < 0)
4608 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004609 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004610 if (status < 0)
4611 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004612
4613
Oliver Endrissebc7de22011-07-03 13:49:44 -03004614 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004615
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004616 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004617 if (status < 0)
4618 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004619 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004620 if (status < 0)
4621 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004622 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004623 if (status < 0)
4624 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004625 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004626 if (status < 0)
4627 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004628 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004629 if (status < 0)
4630 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004631 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004632 if (status < 0)
4633 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004634 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004635 if (status < 0)
4636 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004637 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004638
Oliver Endrissebc7de22011-07-03 13:49:44 -03004639 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004640}
4641
4642/*============================================================================*/
4643
4644/**
4645* \brief QAM64 specific setup
4646* \param demod instance of demod.
4647* \return DRXStatus_t.
4648*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004649static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004650{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004651 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004652
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004653 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004654 do {
4655 /* QAM Equalizer Setup */
4656 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004657 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004658 if (status < 0)
4659 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004660 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004661 if (status < 0)
4662 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004663 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004664 if (status < 0)
4665 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004666 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004667 if (status < 0)
4668 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004669 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004670 if (status < 0)
4671 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004672 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004673 if (status < 0)
4674 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004675
Oliver Endrissebc7de22011-07-03 13:49:44 -03004676 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004677 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004678 if (status < 0)
4679 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004680 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004681 if (status < 0)
4682 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004683 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004684 if (status < 0)
4685 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004686 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004687 if (status < 0)
4688 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004689 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004690 if (status < 0)
4691 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004692 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004693 if (status < 0)
4694 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004695
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004696 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004697 if (status < 0)
4698 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004699 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004700 if (status < 0)
4701 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004702 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004703 if (status < 0)
4704 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004705
4706 /* QAM Slicer Settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004707 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004708 if (status < 0)
4709 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004710
4711
Oliver Endrissebc7de22011-07-03 13:49:44 -03004712 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004713
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004714 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004715 if (status < 0)
4716 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004717 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004718 if (status < 0)
4719 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004720 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004721 if (status < 0)
4722 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004723 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004724 if (status < 0)
4725 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004726 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004727 if (status < 0)
4728 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004729 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004730 if (status < 0)
4731 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004732 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004733 if (status < 0)
4734 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004735 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004736 if (status < 0)
4737 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004738
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004739 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004740 if (status < 0)
4741 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004742 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004743 if (status < 0)
4744 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004745 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004746 if (status < 0)
4747 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004748 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004749 if (status < 0)
4750 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004751 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004752 if (status < 0)
4753 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004754 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004755 if (status < 0)
4756 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004757 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004758 if (status < 0)
4759 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004760 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004761 if (status < 0)
4762 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004763 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004764 if (status < 0)
4765 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004766 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004767 if (status < 0)
4768 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004769 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004770 if (status < 0)
4771 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004772 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004773 if (status < 0)
4774 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004775
4776
Oliver Endrissebc7de22011-07-03 13:49:44 -03004777 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004778
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004779 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004780 if (status < 0)
4781 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004782 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004783 if (status < 0)
4784 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004785 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004786 if (status < 0)
4787 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004788 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004789 if (status < 0)
4790 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004791 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004792 if (status < 0)
4793 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004794 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004795 if (status < 0)
4796 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004797
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004798 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004799 if (status < 0)
4800 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004801 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004802 if (status < 0)
4803 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004804 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004805 if (status < 0)
4806 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004807
4808
Oliver Endrissebc7de22011-07-03 13:49:44 -03004809 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004810
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004811 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004812 if (status < 0)
4813 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004814 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004815 if (status < 0)
4816 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004817 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004818 if (status < 0)
4819 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004820 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004821 if (status < 0)
4822 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004823 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004824 if (status < 0)
4825 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004826 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004827 if (status < 0)
4828 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004829 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004830 if (status < 0)
4831 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004832 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004833
Oliver Endrissebc7de22011-07-03 13:49:44 -03004834 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004835}
4836
4837/*============================================================================*/
4838
4839/**
4840* \brief QAM128 specific setup
4841* \param demod: instance of demod.
4842* \return DRXStatus_t.
4843*/
4844static int SetQAM128(struct drxk_state *state)
4845{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004846 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004847
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004848 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004849 do {
4850 /* QAM Equalizer Setup */
4851 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004852 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004853 if (status < 0)
4854 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004855 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004856 if (status < 0)
4857 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004858 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004859 if (status < 0)
4860 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004861 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004862 if (status < 0)
4863 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004864 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004865 if (status < 0)
4866 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004867 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004868 if (status < 0)
4869 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004870
Oliver Endrissebc7de22011-07-03 13:49:44 -03004871 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004872 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004873 if (status < 0)
4874 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004875 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004876 if (status < 0)
4877 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004878 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004879 if (status < 0)
4880 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004881 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004882 if (status < 0)
4883 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004884 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004885 if (status < 0)
4886 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004887 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004888 if (status < 0)
4889 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004890
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004891 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004892 if (status < 0)
4893 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004894 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004895 if (status < 0)
4896 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004897 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004898 if (status < 0)
4899 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004900
4901
Oliver Endrissebc7de22011-07-03 13:49:44 -03004902 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004903
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004904 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004905 if (status < 0)
4906 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004907
4908
Oliver Endrissebc7de22011-07-03 13:49:44 -03004909 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004910
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004911 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004912 if (status < 0)
4913 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004914 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004915 if (status < 0)
4916 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004917 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004918 if (status < 0)
4919 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004920 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004921 if (status < 0)
4922 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004923 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004924 if (status < 0)
4925 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004926 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004927 if (status < 0)
4928 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004929 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004930 if (status < 0)
4931 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004932 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004933 if (status < 0)
4934 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004935
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004936 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004937 if (status < 0)
4938 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004939 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004940 if (status < 0)
4941 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004942 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004943 if (status < 0)
4944 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004945 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004946 if (status < 0)
4947 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004948 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004949 if (status < 0)
4950 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004951 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004952 if (status < 0)
4953 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004954 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004955 if (status < 0)
4956 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004957 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004958 if (status < 0)
4959 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004960 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004961 if (status < 0)
4962 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004963 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004964 if (status < 0)
4965 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004966 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004967 if (status < 0)
4968 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004969 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004970 if (status < 0)
4971 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004972
4973
Oliver Endrissebc7de22011-07-03 13:49:44 -03004974 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004975
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004976 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004977 if (status < 0)
4978 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004979 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004980 if (status < 0)
4981 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004982 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004983 if (status < 0)
4984 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004985 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004986 if (status < 0)
4987 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004988 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004989 if (status < 0)
4990 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004991 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004992 if (status < 0)
4993 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004994
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004995 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004996 if (status < 0)
4997 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004998 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004999 if (status < 0)
5000 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005001
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005002 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005003 if (status < 0)
5004 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005005
Oliver Endrissebc7de22011-07-03 13:49:44 -03005006 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005007
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005008 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005009 if (status < 0)
5010 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005011 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005012 if (status < 0)
5013 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005014 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005015 if (status < 0)
5016 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005017 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005018 if (status < 0)
5019 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005020 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005021 if (status < 0)
5022 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005023 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005024 if (status < 0)
5025 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005026 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005027 if (status < 0)
5028 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005029 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005030
Oliver Endrissebc7de22011-07-03 13:49:44 -03005031 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005032}
5033
5034/*============================================================================*/
5035
5036/**
5037* \brief QAM256 specific setup
5038* \param demod: instance of demod.
5039* \return DRXStatus_t.
5040*/
5041static int SetQAM256(struct drxk_state *state)
5042{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005043 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005044
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005045 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005046 do {
5047 /* QAM Equalizer Setup */
5048 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005049 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005050 if (status < 0)
5051 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005052 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005053 if (status < 0)
5054 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005055 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005056 if (status < 0)
5057 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005058 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005059 if (status < 0)
5060 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005061 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005062 if (status < 0)
5063 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005064 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005065 if (status < 0)
5066 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005067
Oliver Endrissebc7de22011-07-03 13:49:44 -03005068 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005069 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005070 if (status < 0)
5071 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005072 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005073 if (status < 0)
5074 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005075 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005076 if (status < 0)
5077 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005078 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005079 if (status < 0)
5080 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005081 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005082 if (status < 0)
5083 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005084 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005085 if (status < 0)
5086 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005087
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005088 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005089 if (status < 0)
5090 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005091 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005092 if (status < 0)
5093 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005094 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005095 if (status < 0)
5096 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005097
Oliver Endrissebc7de22011-07-03 13:49:44 -03005098 /* QAM Slicer Settings */
5099
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005100 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005101 if (status < 0)
5102 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005103
5104
Oliver Endrissebc7de22011-07-03 13:49:44 -03005105 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005106
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005107 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005108 if (status < 0)
5109 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005110 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005111 if (status < 0)
5112 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005113 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005114 if (status < 0)
5115 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005116 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005117 if (status < 0)
5118 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005119 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005120 if (status < 0)
5121 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005122 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005123 if (status < 0)
5124 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005125 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005126 if (status < 0)
5127 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005128 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005129 if (status < 0)
5130 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005131
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005132 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005133 if (status < 0)
5134 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005135 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005136 if (status < 0)
5137 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005138 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005139 if (status < 0)
5140 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005141 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005142 if (status < 0)
5143 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005144 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005145 if (status < 0)
5146 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005147 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005148 if (status < 0)
5149 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005150 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005151 if (status < 0)
5152 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005153 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005154 if (status < 0)
5155 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005156 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005157 if (status < 0)
5158 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005159 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005160 if (status < 0)
5161 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005162 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005163 if (status < 0)
5164 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005165 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005166 if (status < 0)
5167 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005168
5169
Oliver Endrissebc7de22011-07-03 13:49:44 -03005170 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005171
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005172 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005173 if (status < 0)
5174 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005175 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005176 if (status < 0)
5177 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005178 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005179 if (status < 0)
5180 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005181 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005182 if (status < 0)
5183 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005184 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005185 if (status < 0)
5186 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005187 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005188 if (status < 0)
5189 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005190
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005191 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005192 if (status < 0)
5193 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005194 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005195 if (status < 0)
5196 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005197 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005198 if (status < 0)
5199 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005200
5201
Oliver Endrissebc7de22011-07-03 13:49:44 -03005202 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005203
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005204 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005205 if (status < 0)
5206 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005207 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005208 if (status < 0)
5209 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005210 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005211 if (status < 0)
5212 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005213 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005214 if (status < 0)
5215 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005216 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005217 if (status < 0)
5218 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005219 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005220 if (status < 0)
5221 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005222 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005223 if (status < 0)
5224 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005225 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005226
Oliver Endrissebc7de22011-07-03 13:49:44 -03005227 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005228}
5229
5230
5231/*============================================================================*/
5232/**
5233* \brief Reset QAM block.
5234* \param demod: instance of demod.
5235* \param channel: pointer to channel data.
5236* \return DRXStatus_t.
5237*/
5238static int QAMResetQAM(struct drxk_state *state)
5239{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005240 int status;
5241 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005242
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005243 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005244 do {
5245 /* Stop QAM comstate->m_exec */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005246 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005247 if (status < 0)
5248 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005249
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005250 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5251 if (status < 0)
5252 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005253 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005254
Oliver Endrissebc7de22011-07-03 13:49:44 -03005255 /* All done, all OK */
5256 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005257}
5258
5259/*============================================================================*/
5260
5261/**
5262* \brief Set QAM symbolrate.
5263* \param demod: instance of demod.
5264* \param channel: pointer to channel data.
5265* \return DRXStatus_t.
5266*/
5267static int QAMSetSymbolrate(struct drxk_state *state)
5268{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005269 u32 adcFrequency = 0;
5270 u32 symbFreq = 0;
5271 u32 iqmRcRate = 0;
5272 u16 ratesel = 0;
5273 u32 lcSymbRate = 0;
5274 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005275
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005276 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005277 do {
5278 /* Select & calculate correct IQM rate */
5279 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5280 ratesel = 0;
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005281 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005282 if (state->param.u.qam.symbol_rate <= 1188750)
5283 ratesel = 3;
5284 else if (state->param.u.qam.symbol_rate <= 2377500)
5285 ratesel = 2;
5286 else if (state->param.u.qam.symbol_rate <= 4755000)
5287 ratesel = 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005288 status = write16(state, IQM_FD_RATESEL__A, ratesel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005289 if (status < 0)
5290 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005291
Oliver Endrissebc7de22011-07-03 13:49:44 -03005292 /*
5293 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5294 */
5295 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5296 if (symbFreq == 0) {
5297 /* Divide by zero */
5298 return -1;
5299 }
5300 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5301 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5302 (1 << 23);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005303 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005304 if (status < 0)
5305 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005306 state->m_iqmRcRate = iqmRcRate;
5307 /*
5308 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5309 */
5310 symbFreq = state->param.u.qam.symbol_rate;
5311 if (adcFrequency == 0) {
5312 /* Divide by zero */
5313 return -1;
5314 }
5315 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5316 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5317 16);
5318 if (lcSymbRate > 511)
5319 lcSymbRate = 511;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005320 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005321 if (status < 0)
5322 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005323 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005324
Oliver Endrissebc7de22011-07-03 13:49:44 -03005325 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005326}
5327
5328/*============================================================================*/
5329
5330/**
5331* \brief Get QAM lock status.
5332* \param demod: instance of demod.
5333* \param channel: pointer to channel data.
5334* \return DRXStatus_t.
5335*/
5336
5337static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5338{
5339 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005340 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005341
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005342 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005343 status =
5344 scu_command(state,
5345 SCU_RAM_COMMAND_STANDARD_QAM |
5346 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5347 Result);
5348 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005349 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005350
5351 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005352 /* 0x0000 NOT LOCKED */
5353 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005354 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005355 /* 0x4000 DEMOD LOCKED */
5356 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005357 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005358 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5359 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005360 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005361 /* 0xC000 NEVER LOCKED */
5362 /* (system will never be able to lock to the signal) */
5363 /* TODO: check this, intermediate & standard specific lock states are not
5364 taken into account here */
5365 *pLockStatus = NEVER_LOCK;
5366 }
5367 return status;
5368}
5369
5370#define QAM_MIRROR__M 0x03
5371#define QAM_MIRROR_NORMAL 0x00
5372#define QAM_MIRRORED 0x01
5373#define QAM_MIRROR_AUTO_ON 0x02
5374#define QAM_LOCKRANGE__M 0x10
5375#define QAM_LOCKRANGE_NORMAL 0x10
5376
Oliver Endrissebc7de22011-07-03 13:49:44 -03005377static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5378 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005379{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005380 int status = 0;
5381 u8 parameterLen;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005382 u16 setEnvParameters[5];
5383 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5384 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005385
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005386 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005387 do {
5388 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005389 STEP 1: reset demodulator
5390 resets FEC DI and FEC RS
5391 resets QAM block
5392 resets SCU variables
5393 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005394 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005395 if (status < 0)
5396 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005397 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005398 if (status < 0)
5399 break;
5400 status = QAMResetQAM(state);
5401 if (status < 0)
5402 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005403
5404 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005405 STEP 2: configure demodulator
5406 -set env
5407 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5408 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005409 status = QAMSetSymbolrate(state);
5410 if (status < 0)
5411 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005412
5413 /* Env parameters */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005414 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005415 if (state->m_OperationMode == OM_QAM_ITU_C)
Oliver Endrissebc7de22011-07-03 13:49:44 -03005416 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005417 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005418 /* check for LOCKRANGE Extented */
5419 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005420 parameterLen = 4;
5421
5422 /* Set params */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005423 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005424 case QAM_256:
5425 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5426 break;
5427 case QAM_AUTO:
5428 case QAM_64:
5429 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5430 break;
5431 case QAM_16:
5432 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5433 break;
5434 case QAM_32:
5435 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5436 break;
5437 case QAM_128:
5438 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5439 break;
5440 default:
5441 status = -EINVAL;
5442 break;
5443 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005444 status = status;
5445 if (status < 0)
5446 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005447 setParamParameters[0] = state->m_Constellation; /* constellation */
5448 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005449
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005450 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5451 if (status < 0)
5452 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005453
5454
5455 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5456 setup constellation independent registers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005457#if 0
5458 status = SetFrequency (channel, tunerFreqOffset));
5459 if (status < 0)
5460 break;
5461#endif
5462 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5463 if (status < 0)
5464 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005465
5466 /* Setup BER measurement */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005467 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5468 if (status < 0)
5469 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005470
5471 /* Reset default values */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005472 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005473 if (status < 0)
5474 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005475 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005476 if (status < 0)
5477 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005478
Oliver Endrissebc7de22011-07-03 13:49:44 -03005479 /* Reset default LC values */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005480 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005481 if (status < 0)
5482 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005483 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005484 if (status < 0)
5485 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005486 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005487 if (status < 0)
5488 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005489 status = write16(state, QAM_LC_MODE__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005490 if (status < 0)
5491 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005492
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005493 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005494 if (status < 0)
5495 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005496 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005497 if (status < 0)
5498 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005499 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005500 if (status < 0)
5501 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005502 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005503 if (status < 0)
5504 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005505 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005506 if (status < 0)
5507 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005508 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005509 if (status < 0)
5510 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005511 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005512 if (status < 0)
5513 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005514 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005515 if (status < 0)
5516 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005517 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005518 if (status < 0)
5519 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005520 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005521 if (status < 0)
5522 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005523 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005524 if (status < 0)
5525 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005526 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005527 if (status < 0)
5528 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005529 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005530 if (status < 0)
5531 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005532 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005533 if (status < 0)
5534 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005535 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005536 if (status < 0)
5537 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005538
Oliver Endrissebc7de22011-07-03 13:49:44 -03005539 /* Mirroring, QAM-block starting point not inverted */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005540 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005541 if (status < 0)
5542 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005543
Oliver Endrissebc7de22011-07-03 13:49:44 -03005544 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005545 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005546 if (status < 0)
5547 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005548
Oliver Endrissebc7de22011-07-03 13:49:44 -03005549 /* STEP 4: constellation specific setup */
5550 switch (state->param.u.qam.modulation) {
5551 case QAM_16:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005552 status = SetQAM16(state);
5553 if (status < 0)
5554 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005555 break;
5556 case QAM_32:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005557 status = SetQAM32(state);
5558 if (status < 0)
5559 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005560 break;
5561 case QAM_AUTO:
5562 case QAM_64:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005563 status = SetQAM64(state);
5564 if (status < 0)
5565 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005566 break;
5567 case QAM_128:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005568 status = SetQAM128(state);
5569 if (status < 0)
5570 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005571 break;
5572 case QAM_256:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005573 status = SetQAM256(state);
5574 if (status < 0)
5575 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005576 break;
5577 default:
5578 return -1;
5579 break;
5580 } /* switch */
5581 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005582 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005583 if (status < 0)
5584 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005585
5586
Oliver Endrissebc7de22011-07-03 13:49:44 -03005587 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5588 /* extAttr->currentChannel.constellation = channel->constellation; */
5589 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005590 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5591 if (status < 0)
5592 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005593
Oliver Endrissebc7de22011-07-03 13:49:44 -03005594 /* Start processes */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005595 status = MPEGTSStart(state);
5596 if (status < 0)
5597 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005598 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005599 if (status < 0)
5600 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005601 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005602 if (status < 0)
5603 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005604 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005605 if (status < 0)
5606 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005607
Oliver Endrissebc7de22011-07-03 13:49:44 -03005608 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005609 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5610 if (status < 0)
5611 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005612
Oliver Endrissebc7de22011-07-03 13:49:44 -03005613 /* update global DRXK data container */
5614 /*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005615
Oliver Endrissebc7de22011-07-03 13:49:44 -03005616 /* All done, all OK */
5617 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005618
Oliver Endrissebc7de22011-07-03 13:49:44 -03005619 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005620 printk(KERN_ERR "drxk: %s %d\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005621
5622 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005623}
5624
Oliver Endrissebc7de22011-07-03 13:49:44 -03005625static int SetQAMStandard(struct drxk_state *state,
5626 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005627{
5628#ifdef DRXK_QAM_TAPS
5629#define DRXK_QAMA_TAPS_SELECT
5630#include "drxk_filters.h"
5631#undef DRXK_QAMA_TAPS_SELECT
5632#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03005633 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005634#endif
5635
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005636 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005637 do {
5638 /* added antenna switch */
5639 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005640
Oliver Endrissebc7de22011-07-03 13:49:44 -03005641 /* Ensure correct power-up mode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005642 status = PowerUpQAM(state);
5643 if (status < 0)
5644 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005645 /* Reset QAM block */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005646 status = QAMResetQAM(state);
5647 if (status < 0)
5648 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005649
Oliver Endrissebc7de22011-07-03 13:49:44 -03005650 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005651
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005652 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005653 if (status < 0)
5654 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005655 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005656 if (status < 0)
5657 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005658
Oliver Endrissebc7de22011-07-03 13:49:44 -03005659 /* Upload IQM Channel Filter settings by
5660 boot loader from ROM table */
5661 switch (oMode) {
5662 case OM_QAM_ITU_A:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005663 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5664 if (status < 0)
5665 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005666 break;
5667 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005668 status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5669 if (status < 0)
5670 break;
5671 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5672 if (status < 0)
5673 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005674 break;
5675 default:
5676 status = -EINVAL;
5677 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005678 status = status;
5679 if (status < 0)
5680 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005681
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005682 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005683 if (status < 0)
5684 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005685 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005686 if (status < 0)
5687 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005688 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 -03005689 if (status < 0)
5690 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005691
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005692 status = write16(state, IQM_RC_STRETCH__A, 21);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005693 if (status < 0)
5694 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005695 status = write16(state, IQM_AF_CLP_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005696 if (status < 0)
5697 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005698 status = write16(state, IQM_AF_CLP_TH__A, 448);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005699 if (status < 0)
5700 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005701 status = write16(state, IQM_AF_SNS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005702 if (status < 0)
5703 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005704 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005705 if (status < 0)
5706 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005707
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005708 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005709 if (status < 0)
5710 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005711 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005712 if (status < 0)
5713 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005714 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005715 if (status < 0)
5716 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005717 status = write16(state, IQM_AF_UPD_SEL__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005718 if (status < 0)
5719 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005720
Oliver Endrissebc7de22011-07-03 13:49:44 -03005721 /* IQM Impulse Noise Processing Unit */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005722 status = write16(state, IQM_CF_CLP_VAL__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005723 if (status < 0)
5724 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005725 status = write16(state, IQM_CF_DATATH__A, 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005726 if (status < 0)
5727 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005728 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005729 if (status < 0)
5730 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005731 status = write16(state, IQM_CF_DET_LCT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005732 if (status < 0)
5733 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005734 status = write16(state, IQM_CF_WND_LEN__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005735 if (status < 0)
5736 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005737 status = write16(state, IQM_CF_PKDTH__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005738 if (status < 0)
5739 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005740 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005741 if (status < 0)
5742 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005743
Oliver Endrissebc7de22011-07-03 13:49:44 -03005744 /* turn on IQMAF. Must be done before setAgc**() */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005745 status = SetIqmAf(state, true);
5746 if (status < 0)
5747 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005748 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005749 if (status < 0)
5750 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005751
Oliver Endrissebc7de22011-07-03 13:49:44 -03005752 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005753 status = ADCSynchronization(state);
5754 if (status < 0)
5755 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005756
Oliver Endrissebc7de22011-07-03 13:49:44 -03005757 /* Set the FSM step period */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005758 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005759 if (status < 0)
5760 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005761
Oliver Endrissebc7de22011-07-03 13:49:44 -03005762 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005763 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005764 if (status < 0)
5765 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005766
Oliver Endrissebc7de22011-07-03 13:49:44 -03005767 /* No more resets of the IQM, current standard correctly set =>
5768 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005769
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005770 status = InitAGC(state, true);
5771 if (status < 0)
5772 break;
5773 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5774 if (status < 0)
5775 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005776
Oliver Endrissebc7de22011-07-03 13:49:44 -03005777 /* Configure AGC's */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005778 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5779 if (status < 0)
5780 break;
5781 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5782 if (status < 0)
5783 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005784
Oliver Endrissebc7de22011-07-03 13:49:44 -03005785 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005786 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005787 if (status < 0)
5788 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005789 } while (0);
5790 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005791}
5792
5793static int WriteGPIO(struct drxk_state *state)
5794{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005795 int status;
5796 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005797
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005798 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005799 do {
5800 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005801 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005802 if (status < 0)
5803 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005804
Oliver Endrissebc7de22011-07-03 13:49:44 -03005805 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005806 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005807 if (status < 0)
5808 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005809
Oliver Endrissebc7de22011-07-03 13:49:44 -03005810 if (state->m_hasSAWSW) {
5811 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005812 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005813 if (status < 0)
5814 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005815
Oliver Endrissebc7de22011-07-03 13:49:44 -03005816 /* use corresponding bit in io data output registar */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005817 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005818 if (status < 0)
5819 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005820 if (state->m_GPIO == 0)
5821 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5822 else
5823 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5824 /* write back to io data output register */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005825 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005826 if (status < 0)
5827 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005828
Oliver Endrissebc7de22011-07-03 13:49:44 -03005829 }
5830 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005831 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005832 if (status < 0)
5833 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005834 } while (0);
5835 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005836}
5837
5838static int SwitchAntennaToQAM(struct drxk_state *state)
5839{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005840 int status = -1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005841
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005842 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005843 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5844 if (state->m_GPIO != state->m_AntennaDVBC) {
5845 state->m_GPIO = state->m_AntennaDVBC;
5846 status = WriteGPIO(state);
5847 }
5848 }
5849 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005850}
5851
5852static int SwitchAntennaToDVBT(struct drxk_state *state)
5853{
5854 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005855
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005856 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005857 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5858 if (state->m_GPIO != state->m_AntennaDVBT) {
5859 state->m_GPIO = state->m_AntennaDVBT;
5860 status = WriteGPIO(state);
5861 }
5862 }
5863 return status;
5864}
5865
5866
5867static int PowerDownDevice(struct drxk_state *state)
5868{
5869 /* Power down to requested mode */
5870 /* Backup some register settings */
5871 /* Set pins with possible pull-ups connected to them in input mode */
5872 /* Analog power down */
5873 /* ADC power down */
5874 /* Power down device */
5875 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005876
5877 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005878 do {
5879 if (state->m_bPDownOpenBridge) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03005880 /* Open I2C bridge before power down of DRXK */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005881 status = ConfigureI2CBridge(state, true);
5882 if (status < 0)
5883 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005884 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005885 /* driver 0.9.0 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005886 status = DVBTEnableOFDMTokenRing(state, false);
5887 if (status < 0)
5888 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005889
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005890 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005891 if (status < 0)
5892 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005893 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005894 if (status < 0)
5895 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005896 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005897 status = HI_CfgCommand(state);
5898 if (status < 0)
5899 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005900 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005901
Oliver Endrissebc7de22011-07-03 13:49:44 -03005902 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005903 return -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005904
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005905 return 0;
5906}
5907
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005908static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005909{
5910 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005911 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005912
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005913 dprintk(1, "\n");
5914
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005915 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5916 if (err < 0) {
5917 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005918 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005919 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005920 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005921 return err;
5922 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005923 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005924 release_firmware(fw);
5925 return err;
5926}
5927
5928static int init_drxk(struct drxk_state *state)
5929{
5930 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005931 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005932 u16 driverVersion;
5933
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005934 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005935 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
5936 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005937 status = PowerUpDevice(state);
5938 if (status < 0)
5939 break;
5940 status = DRXX_Open(state);
5941 if (status < 0)
5942 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005943 /* Soft reset of OFDM-, sys- and osc-clockdomain */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005944 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 -03005945 if (status < 0)
5946 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005947 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005948 if (status < 0)
5949 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005950 /* TODO is this needed, if yes how much delay in worst case scenario */
5951 msleep(1);
5952 state->m_DRXK_A3_PATCH_CODE = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005953 status = GetDeviceCapabilities(state);
5954 if (status < 0)
5955 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005956
5957 /* Bridge delay, uses oscilator clock */
5958 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5959 /* SDA brdige delay */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005960 state->m_HICfgBridgeDelay =
5961 (u16) ((state->m_oscClockFreq / 1000) *
5962 HI_I2C_BRIDGE_DELAY) / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005963 /* Clipping */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005964 if (state->m_HICfgBridgeDelay >
5965 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
5966 state->m_HICfgBridgeDelay =
5967 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005968 }
5969 /* SCL bridge delay, same as SDA for now */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005970 state->m_HICfgBridgeDelay +=
5971 state->m_HICfgBridgeDelay <<
5972 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005973
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005974 status = InitHI(state);
5975 if (status < 0)
5976 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005977 /* disable various processes */
5978#if NOA1ROM
Oliver Endrissebc7de22011-07-03 13:49:44 -03005979 if (!(state->m_DRXK_A1_ROM_CODE)
5980 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005981#endif
5982 {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005983 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005984 if (status < 0)
5985 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005986 }
5987
5988 /* disable MPEG port */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005989 status = MPEGTSDisable(state);
5990 if (status < 0)
5991 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005992
5993 /* Stop AUD and SCU */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005994 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005995 if (status < 0)
5996 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005997 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005998 if (status < 0)
5999 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006000
6001 /* enable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006002 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 -03006003 if (status < 0)
6004 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006005
6006 /* include boot loader section */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006007 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006008 if (status < 0)
6009 break;
6010 status = BLChainCmd(state, 0, 6, 100);
6011 if (status < 0)
6012 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006013
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006014 if (!state->microcode_name)
6015 load_microcode(state, "drxk_a3.mc");
6016 else
6017 load_microcode(state, state->microcode_name);
6018
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006019 /* disable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006020 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 -03006021 if (status < 0)
6022 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006023
6024 /* Run SCU for a little while to initialize microcode version numbers */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006025 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006026 if (status < 0)
6027 break;
6028 status = DRXX_Open(state);
6029 if (status < 0)
6030 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006031 /* added for test */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006032 msleep(30);
6033
6034 powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006035 status = CtrlPowerMode(state, &powerMode);
6036 if (status < 0)
6037 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006038
6039 /* Stamp driver version number in SCU data RAM in BCD code
6040 Done to enable field application engineers to retreive drxdriver version
6041 via I2C from SCU RAM.
6042 Not using SCU command interface for SCU register access since no
6043 microcode may be present.
Oliver Endrissebc7de22011-07-03 13:49:44 -03006044 */
6045 driverVersion =
6046 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6047 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6048 ((DRXK_VERSION_MAJOR % 10) << 4) +
6049 (DRXK_VERSION_MINOR % 10);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006050 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006051 if (status < 0)
6052 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006053 driverVersion =
6054 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6055 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6056 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6057 (DRXK_VERSION_PATCH % 10);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006058 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006059 if (status < 0)
6060 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006061
Oliver Endrissebc7de22011-07-03 13:49:44 -03006062 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6063 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6064 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006065
6066 /* Dirty fix of default values for ROM/PATCH microcode
6067 Dirty because this fix makes it impossible to setup suitable values
6068 before calling DRX_Open. This solution requires changes to RF AGC speed
6069 to be done via the CTRL function after calling DRX_Open */
6070
Oliver Endrissebc7de22011-07-03 13:49:44 -03006071 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006072
6073 /* Reset driver debug flags to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006074 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006075 if (status < 0)
6076 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006077 /* driver 0.9.0 */
6078 /* Setup FEC OC:
6079 NOTE: No more full FEC resets allowed afterwards!! */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006080 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006081 if (status < 0)
6082 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006083 /* MPEGTS functions are still the same */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006084 status = MPEGTSDtoInit(state);
6085 if (status < 0)
6086 break;
6087 status = MPEGTSStop(state);
6088 if (status < 0)
6089 break;
6090 status = MPEGTSConfigurePolarity(state);
6091 if (status < 0)
6092 break;
6093 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6094 if (status < 0)
6095 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006096 /* added: configure GPIO */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006097 status = WriteGPIO(state);
6098 if (status < 0)
6099 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006100
Oliver Endrissebc7de22011-07-03 13:49:44 -03006101 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006102
6103 if (state->m_bPowerDown) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006104 status = PowerDownDevice(state);
6105 if (status < 0)
6106 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006107 state->m_DrxkState = DRXK_POWERED_DOWN;
6108 } else
6109 state->m_DrxkState = DRXK_STOPPED;
6110 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006111 }
6112
6113 return 0;
6114}
6115
Oliver Endrissebc7de22011-07-03 13:49:44 -03006116static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006117{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006118 struct drxk_state *state = fe->demodulator_priv;
6119
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006120 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006121 kfree(state);
6122}
6123
Oliver Endrissebc7de22011-07-03 13:49:44 -03006124static int drxk_c_init(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;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006127
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006128 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006129 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006130 return -EBUSY;
6131 SetOperationMode(state, OM_QAM_ITU_A);
6132 return 0;
6133}
6134
Oliver Endrissebc7de22011-07-03 13:49:44 -03006135static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006136{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006137 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006138
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006139 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006140 ShutDown(state);
6141 mutex_unlock(&state->ctlock);
6142 return 0;
6143}
6144
Oliver Endrissebc7de22011-07-03 13:49:44 -03006145static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006146{
6147 struct drxk_state *state = fe->demodulator_priv;
6148
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006149 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006150 return ConfigureI2CBridge(state, enable ? true : false);
6151}
6152
Oliver Endrissebc7de22011-07-03 13:49:44 -03006153static int drxk_set_parameters(struct dvb_frontend *fe,
6154 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006155{
6156 struct drxk_state *state = fe->demodulator_priv;
6157 u32 IF;
6158
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006159 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006160 if (fe->ops.i2c_gate_ctrl)
6161 fe->ops.i2c_gate_ctrl(fe, 1);
6162 if (fe->ops.tuner_ops.set_params)
6163 fe->ops.tuner_ops.set_params(fe, p);
6164 if (fe->ops.i2c_gate_ctrl)
6165 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006166 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006167 fe->ops.tuner_ops.get_frequency(fe, &IF);
6168 Start(state, 0, IF);
6169
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006170 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006171
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006172 return 0;
6173}
6174
Oliver Endrissebc7de22011-07-03 13:49:44 -03006175static int drxk_c_get_frontend(struct dvb_frontend *fe,
6176 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006177{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006178 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006179 return 0;
6180}
6181
6182static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6183{
6184 struct drxk_state *state = fe->demodulator_priv;
6185 u32 stat;
6186
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006187 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006188 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006189 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006190 if (stat == MPEG_LOCK)
6191 *status |= 0x1f;
6192 if (stat == FEC_LOCK)
6193 *status |= 0x0f;
6194 if (stat == DEMOD_LOCK)
6195 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006196 return 0;
6197}
6198
6199static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6200{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006201 dprintk(1, "\n");
6202
Oliver Endrissebc7de22011-07-03 13:49:44 -03006203 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006204 return 0;
6205}
6206
Oliver Endrissebc7de22011-07-03 13:49:44 -03006207static int drxk_read_signal_strength(struct dvb_frontend *fe,
6208 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006209{
6210 struct drxk_state *state = fe->demodulator_priv;
6211 u32 val;
6212
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006213 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006214 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006215 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006216 return 0;
6217}
6218
6219static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6220{
6221 struct drxk_state *state = fe->demodulator_priv;
6222 s32 snr2;
6223
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006224 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006225 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006226 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006227 return 0;
6228}
6229
6230static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6231{
6232 struct drxk_state *state = fe->demodulator_priv;
6233 u16 err;
6234
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006235 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006236 DVBTQAMGetAccPktErr(state, &err);
6237 *ucblocks = (u32) err;
6238 return 0;
6239}
6240
Oliver Endrissebc7de22011-07-03 13:49:44 -03006241static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6242 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006243{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006244 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006245 sets->min_delay_ms = 3000;
6246 sets->max_drift = 0;
6247 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006248 return 0;
6249}
6250
Oliver Endrissebc7de22011-07-03 13:49:44 -03006251static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006252{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006253#if 0
6254 struct drxk_state *state = fe->demodulator_priv;
6255
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006256 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006257 kfree(state);
6258#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006259}
6260
Oliver Endrissebc7de22011-07-03 13:49:44 -03006261static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006262{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006263 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006264
6265 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006266 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006267 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006268 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006269 return 0;
6270}
6271
Oliver Endrissebc7de22011-07-03 13:49:44 -03006272static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006273{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006274 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006275
6276 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006277 mutex_unlock(&state->ctlock);
6278 return 0;
6279}
6280
Oliver Endrissebc7de22011-07-03 13:49:44 -03006281static int drxk_t_get_frontend(struct dvb_frontend *fe,
6282 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006283{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006284 dprintk(1, "\n");
6285
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006286 return 0;
6287}
6288
6289static struct dvb_frontend_ops drxk_c_ops = {
6290 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006291 .name = "DRXK DVB-C",
6292 .type = FE_QAM,
6293 .frequency_stepsize = 62500,
6294 .frequency_min = 47000000,
6295 .frequency_max = 862000000,
6296 .symbol_rate_min = 870000,
6297 .symbol_rate_max = 11700000,
6298 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6299 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006300 .release = drxk_c_release,
6301 .init = drxk_c_init,
6302 .sleep = drxk_c_sleep,
6303 .i2c_gate_ctrl = drxk_gate_ctrl,
6304
6305 .set_frontend = drxk_set_parameters,
6306 .get_frontend = drxk_c_get_frontend,
6307 .get_tune_settings = drxk_c_get_tune_settings,
6308
6309 .read_status = drxk_read_status,
6310 .read_ber = drxk_read_ber,
6311 .read_signal_strength = drxk_read_signal_strength,
6312 .read_snr = drxk_read_snr,
6313 .read_ucblocks = drxk_read_ucblocks,
6314};
6315
6316static struct dvb_frontend_ops drxk_t_ops = {
6317 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006318 .name = "DRXK DVB-T",
6319 .type = FE_OFDM,
6320 .frequency_min = 47125000,
6321 .frequency_max = 865000000,
6322 .frequency_stepsize = 166667,
6323 .frequency_tolerance = 0,
6324 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6325 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6326 FE_CAN_FEC_AUTO |
6327 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6328 FE_CAN_QAM_AUTO |
6329 FE_CAN_TRANSMISSION_MODE_AUTO |
6330 FE_CAN_GUARD_INTERVAL_AUTO |
6331 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006332 .release = drxk_t_release,
6333 .init = drxk_t_init,
6334 .sleep = drxk_t_sleep,
6335 .i2c_gate_ctrl = drxk_gate_ctrl,
6336
6337 .set_frontend = drxk_set_parameters,
6338 .get_frontend = drxk_t_get_frontend,
6339
6340 .read_status = drxk_read_status,
6341 .read_ber = drxk_read_ber,
6342 .read_signal_strength = drxk_read_signal_strength,
6343 .read_snr = drxk_read_snr,
6344 .read_ucblocks = drxk_read_ucblocks,
6345};
6346
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006347struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6348 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006349 struct dvb_frontend **fe_t)
6350{
6351 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006352 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006353
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006354 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006355 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006356 if (!state)
6357 return NULL;
6358
Oliver Endrissebc7de22011-07-03 13:49:44 -03006359 state->i2c = i2c;
6360 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006361 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006362 state->microcode_name = config->microcode_name;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006363
6364 mutex_init(&state->mutex);
6365 mutex_init(&state->ctlock);
6366
Oliver Endrissebc7de22011-07-03 13:49:44 -03006367 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6368 sizeof(struct dvb_frontend_ops));
6369 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6370 sizeof(struct dvb_frontend_ops));
6371 state->c_frontend.demodulator_priv = state;
6372 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006373
6374 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006375 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006376 goto error;
6377 *fe_t = &state->t_frontend;
6378 return &state->c_frontend;
6379
6380error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006381 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006382 kfree(state);
6383 return NULL;
6384}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006385EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006386
6387MODULE_DESCRIPTION("DRX-K driver");
6388MODULE_AUTHOR("Ralph Metzler");
6389MODULE_LICENSE("GPL");