blob: 523352670e73ab187bd16f0f947fc114f2c0c4b0 [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
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002787 if (state->no_i2c_bridge)
2788 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002789 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002790 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 -03002791 if (status < 0)
2792 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002793 if (bEnableBridge) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002794 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 -03002795 if (status < 0)
2796 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002797 } else {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002798 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 -03002799 if (status < 0)
2800 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002801 }
2802
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002803 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2804 if (status < 0)
2805 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002806 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002807 return status;
2808}
2809
Oliver Endrissebc7de22011-07-03 13:49:44 -03002810static int SetPreSaw(struct drxk_state *state,
2811 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002812{
2813 int status;
2814
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002815 dprintk(1, "\n");
2816
Oliver Endrissebc7de22011-07-03 13:49:44 -03002817 if ((pPreSawCfg == NULL)
2818 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002819 return -1;
2820
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002821 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002822 return status;
2823}
2824
2825static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002826 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002827{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002828 u16 blStatus = 0;
2829 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2830 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2831 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002832 unsigned long end;
2833
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002834 dprintk(1, "\n");
2835
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002836 mutex_lock(&state->mutex);
2837 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002838 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002839 if (status < 0)
2840 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002841 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002842 if (status < 0)
2843 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002844 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002845 if (status < 0)
2846 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002847 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002848 if (status < 0)
2849 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002850 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002851 if (status < 0)
2852 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002853 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002854 if (status < 0)
2855 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002856
Oliver Endrissebc7de22011-07-03 13:49:44 -03002857 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002858 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002859 status = read16(state, SIO_BL_STATUS__A, &blStatus);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002860 if (status < 0)
2861 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002862 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002863 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03002864 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002865 mutex_unlock(&state->mutex);
2866 return -1;
2867 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03002868 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002869 mutex_unlock(&state->mutex);
2870 return status;
2871
2872}
2873
Oliver Endrissebc7de22011-07-03 13:49:44 -03002874static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002875{
2876 u16 data = 0;
2877 int status;
2878
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002879 dprintk(1, "\n");
2880
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002881 do {
2882 /* Start measurement */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002883 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002884 if (status < 0)
2885 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002886 status = write16(state, IQM_AF_START_LOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002887 if (status < 0)
2888 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002889
2890 *count = 0;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002891 status = read16(state, IQM_AF_PHASE0__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002892 if (status < 0)
2893 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002894 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002895 *count = *count + 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002896 status = read16(state, IQM_AF_PHASE1__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002897 if (status < 0)
2898 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002899 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002900 *count = *count + 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002901 status = read16(state, IQM_AF_PHASE2__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002902 if (status < 0)
2903 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002904 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002905 *count = *count + 1;
2906 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002907 return status;
2908}
2909
2910static int ADCSynchronization(struct drxk_state *state)
2911{
2912 u16 count = 0;
2913 int status;
2914
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002915 dprintk(1, "\n");
2916
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002917 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002918 status = ADCSyncMeasurement(state, &count);
2919 if (status < 0)
2920 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002921
Oliver Endrissebc7de22011-07-03 13:49:44 -03002922 if (count == 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002923 /* Try sampling on a diffrent edge */
2924 u16 clkNeg = 0;
2925
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002926 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002927 if (status < 0)
2928 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002929 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002930 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2931 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2932 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002933 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002934 } else {
2935 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2936 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002937 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002938 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002939 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002940 if (status < 0)
2941 break;
2942 status = ADCSyncMeasurement(state, &count);
2943 if (status < 0)
2944 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002945 }
2946
2947 if (count < 2)
2948 status = -1;
2949 } while (0);
2950 return status;
2951}
2952
2953static int SetFrequencyShifter(struct drxk_state *state,
2954 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002955 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002956{
2957 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002958 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002959 u32 fmFrequencyShift = 0;
2960 bool tunerMirror = !state->m_bMirrorFreqSpect;
2961 u32 adcFreq;
2962 bool adcFlip;
2963 int status;
2964 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002965 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002966 u32 frequencyShift;
2967 bool imageToSelect;
2968
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002969 dprintk(1, "\n");
2970
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002971 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03002972 Program frequency shifter
2973 No need to account for mirroring on RF
2974 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002975 if (isDTV) {
2976 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
2977 (state->m_OperationMode == OM_QAM_ITU_C) ||
2978 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03002979 selectPosImage = true;
2980 else
2981 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002982 }
2983 if (tunerMirror)
2984 /* tuner doesn't mirror */
2985 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03002986 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002987 else
2988 /* tuner mirrors */
2989 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002990 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002991 if (ifFreqActual > samplingFrequency / 2) {
2992 /* adc mirrors */
2993 adcFreq = samplingFrequency - ifFreqActual;
2994 adcFlip = true;
2995 } else {
2996 /* adc doesn't mirror */
2997 adcFreq = ifFreqActual;
2998 adcFlip = false;
2999 }
3000
3001 frequencyShift = adcFreq;
3002 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003003 adcFlip ^ selectPosImage;
3004 state->m_IqmFsRateOfs =
3005 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003006
3007 if (imageToSelect)
3008 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3009
3010 /* Program frequency shifter with tuner offset compensation */
3011 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003012 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3013 state->m_IqmFsRateOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003014 return status;
3015}
3016
3017static int InitAGC(struct drxk_state *state, bool isDTV)
3018{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003019 u16 ingainTgt = 0;
3020 u16 ingainTgtMin = 0;
3021 u16 ingainTgtMax = 0;
3022 u16 clpCyclen = 0;
3023 u16 clpSumMin = 0;
3024 u16 clpDirTo = 0;
3025 u16 snsSumMin = 0;
3026 u16 snsSumMax = 0;
3027 u16 clpSumMax = 0;
3028 u16 snsDirTo = 0;
3029 u16 kiInnergainMin = 0;
3030 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003031 u16 ifIaccuHiTgtMin = 0;
3032 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003033 u16 data = 0;
3034 u16 fastClpCtrlDelay = 0;
3035 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003036 int status = 0;
3037
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003038 dprintk(1, "\n");
3039
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003040 do {
3041 /* Common settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003042 snsSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003043 ifIaccuHiTgtMin = 2047;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003044 clpCyclen = 500;
3045 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003046
3047 if (IsQAM(state)) {
3048 /* Standard specific settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003049 clpSumMin = 8;
3050 clpDirTo = (u16) -9;
3051 clpCtrlMode = 0;
3052 snsSumMin = 8;
3053 snsDirTo = (u16) -9;
3054 kiInnergainMin = (u16) -1030;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003055 } else
3056 status = -1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003057 status = (status);
3058 if (status < 0)
3059 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003060 if (IsQAM(state)) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003061 ifIaccuHiTgtMax = 0x2380;
3062 ifIaccuHiTgt = 0x2380;
3063 ingainTgtMin = 0x0511;
3064 ingainTgt = 0x0511;
3065 ingainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003066 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003067 state->m_qamIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003068 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003069 ifIaccuHiTgtMax = 0x1200;
3070 ifIaccuHiTgt = 0x1200;
3071 ingainTgtMin = 13424;
3072 ingainTgt = 13424;
3073 ingainTgtMax = 30000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003074 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003075 state->m_dvbtIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003076 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003077 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003078 if (status < 0)
3079 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003080
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003081 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003082 if (status < 0)
3083 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003084 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003085 if (status < 0)
3086 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003087 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003088 if (status < 0)
3089 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003090 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003091 if (status < 0)
3092 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003093 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003094 if (status < 0)
3095 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003096 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003097 if (status < 0)
3098 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003099 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003100 if (status < 0)
3101 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003102 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003103 if (status < 0)
3104 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003105 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003106 if (status < 0)
3107 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003108 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003109 if (status < 0)
3110 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003111 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003112 if (status < 0)
3113 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003114 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003115 if (status < 0)
3116 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003117
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003118 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003119 if (status < 0)
3120 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003121 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003122 if (status < 0)
3123 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003124 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003125 if (status < 0)
3126 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003127
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003128 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003129 if (status < 0)
3130 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003131 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003132 if (status < 0)
3133 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003134 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003135 if (status < 0)
3136 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003137
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003138 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003139 if (status < 0)
3140 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003141 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003142 if (status < 0)
3143 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003144 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003145 if (status < 0)
3146 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003147 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003148 if (status < 0)
3149 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003150 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003151 if (status < 0)
3152 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003153 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003154 if (status < 0)
3155 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003156 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003157 if (status < 0)
3158 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003159 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003160 if (status < 0)
3161 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003162 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003163 if (status < 0)
3164 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003165 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003166 if (status < 0)
3167 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003168 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003169 if (status < 0)
3170 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003171 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003172 if (status < 0)
3173 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003174 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003175 if (status < 0)
3176 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003177 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003178 if (status < 0)
3179 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003180 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003181 if (status < 0)
3182 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003183 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003184 if (status < 0)
3185 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003186 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003187 if (status < 0)
3188 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003189 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003190 if (status < 0)
3191 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003192 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003193 if (status < 0)
3194 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003195
3196 /* Initialize inner-loop KI gain factors */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003197 status = read16(state, SCU_RAM_AGC_KI__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003198 if (status < 0)
3199 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003200 if (IsQAM(state)) {
3201 data = 0x0657;
3202 data &= ~SCU_RAM_AGC_KI_RF__M;
3203 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3204 data &= ~SCU_RAM_AGC_KI_IF__M;
3205 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3206 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003207 status = write16(state, SCU_RAM_AGC_KI__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003208 if (status < 0)
3209 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003210 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003211 return status;
3212}
3213
Oliver Endrissebc7de22011-07-03 13:49:44 -03003214static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003215{
3216 int status;
3217
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003218 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003219 do {
3220 if (packetErr == NULL) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003221 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003222 if (status < 0)
3223 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003224 } else {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003225 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003226 if (status < 0)
3227 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003228 }
3229 } while (0);
3230 return status;
3231}
3232
3233static int DVBTScCommand(struct drxk_state *state,
3234 u16 cmd, u16 subcmd,
3235 u16 param0, u16 param1, u16 param2,
3236 u16 param3, u16 param4)
3237{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003238 u16 curCmd = 0;
3239 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003240 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003241 u16 scExec = 0;
3242 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003243
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003244 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003245 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003246 if (scExec != 1) {
3247 /* SC is not running */
3248 return -1;
3249 }
3250
3251 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003252 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003253 do {
3254 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003255 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003256 retryCnt++;
3257 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
3258 if (retryCnt >= DRXK_MAX_RETRIES)
3259 return -1;
3260 /* Write sub-command */
3261 switch (cmd) {
3262 /* All commands using sub-cmd */
3263 case OFDM_SC_RA_RAM_CMD_PROC_START:
3264 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3265 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003266 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003267 write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003268 break;
3269 default:
3270 /* Do nothing */
3271 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003272 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003273
3274 /* Write needed parameters and the command */
3275 switch (cmd) {
3276 /* All commands using 5 parameters */
3277 /* All commands using 4 parameters */
3278 /* All commands using 3 parameters */
3279 /* All commands using 2 parameters */
3280 case OFDM_SC_RA_RAM_CMD_PROC_START:
3281 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3282 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003283 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003284 write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003285 /* All commands using 1 parameters */
3286 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3287 case OFDM_SC_RA_RAM_CMD_USER_IO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003288 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003289 write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003290 /* All commands using 0 parameters */
3291 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3292 case OFDM_SC_RA_RAM_CMD_NULL:
3293 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003294 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003295 break;
3296 default:
3297 /* Unknown command */
3298 return -EINVAL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003299 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003300
3301 /* Wait until sc is ready processing command */
3302 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003303 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003304 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003305 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003306 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003307 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003308 if (retryCnt >= DRXK_MAX_RETRIES)
3309 return -1;
3310
3311 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003312 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003313 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003314 /* illegal command */
3315 return -EINVAL;
3316 }
3317
3318 /* Retreive results parameters from SC */
3319 switch (cmd) {
3320 /* All commands yielding 5 results */
3321 /* All commands yielding 4 results */
3322 /* All commands yielding 3 results */
3323 /* All commands yielding 2 results */
3324 /* All commands yielding 1 result */
3325 case OFDM_SC_RA_RAM_CMD_USER_IO:
3326 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003327 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003328 read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003329 /* All commands yielding 0 results */
3330 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3331 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3332 case OFDM_SC_RA_RAM_CMD_PROC_START:
3333 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3334 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3335 case OFDM_SC_RA_RAM_CMD_NULL:
3336 break;
3337 default:
3338 /* Unknown command */
3339 return -EINVAL;
3340 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003341 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003342 return status;
3343}
3344
Oliver Endrissebc7de22011-07-03 13:49:44 -03003345static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003346{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003347 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003348 int status;
3349
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003350 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003351 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003352 status = CtrlPowerMode(state, &powerMode);
3353 if (status < 0)
3354 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003355 } while (0);
3356 return status;
3357}
3358
Oliver Endrissebc7de22011-07-03 13:49:44 -03003359static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003360{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003361 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003362
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003363 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003364 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003365 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003366 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003367 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003368
3369 return status;
3370}
3371
3372#define DEFAULT_FR_THRES_8K 4000
3373static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3374{
3375
3376 int status;
3377
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003378 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003379 if (*enabled == true) {
3380 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003381 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003382 DEFAULT_FR_THRES_8K);
3383 } else {
3384 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003385 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003386 }
3387
3388 return status;
3389}
3390
3391static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3392 struct DRXKCfgDvbtEchoThres_t *echoThres)
3393{
3394 u16 data = 0;
3395 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003396
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003397 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003398 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003399 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003400 if (status < 0)
3401 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003402
Oliver Endrissebc7de22011-07-03 13:49:44 -03003403 switch (echoThres->fftMode) {
3404 case DRX_FFTMODE_2K:
3405 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3406 data |=
3407 ((echoThres->threshold <<
3408 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3409 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3410 break;
3411 case DRX_FFTMODE_8K:
3412 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3413 data |=
3414 ((echoThres->threshold <<
3415 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3416 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3417 break;
3418 default:
3419 return -1;
3420 break;
3421 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003422
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003423 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003424 if (status < 0)
3425 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003426 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003427
Oliver Endrissebc7de22011-07-03 13:49:44 -03003428 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003429}
3430
3431static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003432 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003433{
3434 int status;
3435
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003436 dprintk(1, "\n");
3437
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003438 switch (*speed) {
3439 case DRXK_DVBT_SQI_SPEED_FAST:
3440 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3441 case DRXK_DVBT_SQI_SPEED_SLOW:
3442 break;
3443 default:
3444 return -EINVAL;
3445 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003446 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003447 (u16) *speed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003448 return status;
3449}
3450
3451/*============================================================================*/
3452
3453/**
3454* \brief Activate DVBT specific presets
3455* \param demod instance of demodulator.
3456* \return DRXStatus_t.
3457*
3458* Called in DVBTSetStandard
3459*
3460*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003461static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003462{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003463 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003464
Oliver Endrissebc7de22011-07-03 13:49:44 -03003465 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3466 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003467
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003468 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003469 do {
3470 bool setincenable = false;
3471 bool setfrenable = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003472 status = DVBTCtrlSetIncEnable(state, &setincenable);
3473 if (status < 0)
3474 break;
3475 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3476 if (status < 0)
3477 break;
3478 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3479 if (status < 0)
3480 break;
3481 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3482 if (status < 0)
3483 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003484 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003485 if (status < 0)
3486 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003487 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003488
Oliver Endrissebc7de22011-07-03 13:49:44 -03003489 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003490}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003491
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003492/*============================================================================*/
3493
3494/**
3495* \brief Initialize channelswitch-independent settings for DVBT.
3496* \param demod instance of demodulator.
3497* \return DRXStatus_t.
3498*
3499* For ROM code channel filter taps are loaded from the bootloader. For microcode
3500* the DVB-T taps from the drxk_filters.h are used.
3501*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003502static int SetDVBTStandard(struct drxk_state *state,
3503 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003504{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003505 u16 cmdResult = 0;
3506 u16 data = 0;
3507 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003508
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003509 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003510
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003511 PowerUpDVBT(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003512 do {
3513 /* added antenna switch */
3514 SwitchAntennaToDVBT(state);
3515 /* send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003516 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
3517 if (status < 0)
3518 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003519
3520 /* send OFDM setenv command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003521 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3522 if (status < 0)
3523 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003524
3525 /* reset datapath for OFDM, processors first */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003526 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003527 if (status < 0)
3528 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003529 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003530 if (status < 0)
3531 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003532 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003533 if (status < 0)
3534 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003535
3536 /* IQM setup */
3537 /* synchronize on ofdstate->m_festart */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003538 status = write16(state, IQM_AF_UPD_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003539 if (status < 0)
3540 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003541 /* window size for clipping ADC detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003542 status = write16(state, IQM_AF_CLP_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003543 if (status < 0)
3544 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003545 /* window size for for sense pre-SAW detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003546 status = write16(state, IQM_AF_SNS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003547 if (status < 0)
3548 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003549 /* sense threshold for sense pre-SAW detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003550 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003551 if (status < 0)
3552 break;
3553 status = SetIqmAf(state, true);
3554 if (status < 0)
3555 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003556
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003557 status = write16(state, IQM_AF_AGC_RF__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003558 if (status < 0)
3559 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003560
3561 /* Impulse noise cruncher setup */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003562 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003563 if (status < 0)
3564 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003565 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003566 if (status < 0)
3567 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003568 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003569 if (status < 0)
3570 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003571
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003572 status = write16(state, IQM_RC_STRETCH__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003573 if (status < 0)
3574 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003575 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003576 if (status < 0)
3577 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003578 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003579 if (status < 0)
3580 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003581 status = write16(state, IQM_CF_SCALE__A, 1600);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003582 if (status < 0)
3583 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003584 status = write16(state, IQM_CF_SCALE_SH__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003585 if (status < 0)
3586 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003587
3588 /* virtual clipping threshold for clipping ADC detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003589 status = write16(state, IQM_AF_CLP_TH__A, 448);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003590 if (status < 0)
3591 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003592 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003593 if (status < 0)
3594 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003595
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003596 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3597 if (status < 0)
3598 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003599
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003600 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003601 if (status < 0)
3602 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003603 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003604 if (status < 0)
3605 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003606 /* enable power measurement interrupt */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003607 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003608 if (status < 0)
3609 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003610 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003611 if (status < 0)
3612 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003613
3614 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003615 status = ADCSynchronization(state);
3616 if (status < 0)
3617 break;
3618 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3619 if (status < 0)
3620 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003621
3622 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003623 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003624 if (status < 0)
3625 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003626
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003627 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3628 if (status < 0)
3629 break;
3630 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3631 if (status < 0)
3632 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003633
3634 /* Set Noise Estimation notch width and enable DC fix */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003635 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003636 if (status < 0)
3637 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003638 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003639 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003640 if (status < 0)
3641 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003642
3643 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003644 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003645 if (status < 0)
3646 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003647
Oliver Endrissebc7de22011-07-03 13:49:44 -03003648 if (!state->m_DRXK_A3_ROM_CODE) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003649 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003650 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003651 if (status < 0)
3652 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003653 }
3654
3655 /* OFDM_SC setup */
3656#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003657 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003658 if (status < 0)
3659 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003660 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003661 if (status < 0)
3662 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003663#endif
3664
3665 /* FEC setup */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003666 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003667 if (status < 0)
3668 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003669
3670
3671#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003672 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003673 if (status < 0)
3674 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003675#else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003676 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003677 if (status < 0)
3678 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003679#endif
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003680 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003681 if (status < 0)
3682 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003683
3684 /* Setup MPEG bus */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003685 status = MPEGTSDtoSetup(state, OM_DVBT);
3686 if (status < 0)
3687 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003688 /* Set DVBT Presets */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003689 status = DVBTActivatePresets(state);
3690 if (status < 0)
3691 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003692
3693 } while (0);
3694
Oliver Endrissebc7de22011-07-03 13:49:44 -03003695 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003696 printk(KERN_ERR "drxk: %s status - %08x\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003697
3698 return status;
3699}
3700
3701/*============================================================================*/
3702/**
3703* \brief Start dvbt demodulating for channel.
3704* \param demod instance of demodulator.
3705* \return DRXStatus_t.
3706*/
3707static int DVBTStart(struct drxk_state *state)
3708{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003709 u16 param1;
3710 int status;
3711 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003712
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003713 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003714 /* Start correct processes to get in lock */
3715 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
3716 do {
3717 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003718 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3719 if (status < 0)
3720 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003721 /* Start FEC OC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003722 status = MPEGTSStart(state);
3723 if (status < 0)
3724 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003725 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003726 if (status < 0)
3727 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003728 } while (0);
3729 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003730}
3731
3732
3733/*============================================================================*/
3734
3735/**
3736* \brief Set up dvbt demodulator for channel.
3737* \param demod instance of demodulator.
3738* \return DRXStatus_t.
3739* // original DVBTSetChannel()
3740*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003741static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3742 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003743{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003744 u16 cmdResult = 0;
3745 u16 transmissionParams = 0;
3746 u16 operationMode = 0;
3747 u32 iqmRcRateOfs = 0;
3748 u32 bandwidth = 0;
3749 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003750 int status;
3751
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003752 dprintk(1, "\n");
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003753 /* printk(KERN_DEBUG "drxk: %s IF =%d, TFO = %d\n", __func__, IntermediateFreqkHz, tunerFreqOffset); */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003754 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003755 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3756 if (status < 0)
3757 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003758
3759 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003760 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003761 if (status < 0)
3762 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003763
3764 /* Stop processors */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003765 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003766 if (status < 0)
3767 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003768 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003769 if (status < 0)
3770 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003771
3772 /* Mandatory fix, always stop CP, required to set spl offset back to
3773 hardware default (is set to 0 by ucode during pilot detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003774 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003775 if (status < 0)
3776 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003777
3778 /*== Write channel settings to device =====================================*/
3779
3780 /* mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003781 switch (state->param.u.ofdm.transmission_mode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003782 case TRANSMISSION_MODE_AUTO:
3783 default:
3784 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3785 /* fall through , try first guess DRX_FFTMODE_8K */
3786 case TRANSMISSION_MODE_8K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003787 transmissionParams |=
3788 OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003789 break;
3790 case TRANSMISSION_MODE_2K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003791 transmissionParams |=
3792 OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003793 break;
3794 }
3795
3796 /* guard */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003797 switch (state->param.u.ofdm.guard_interval) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003798 default:
3799 case GUARD_INTERVAL_AUTO:
3800 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3801 /* fall through , try first guess DRX_GUARD_1DIV4 */
3802 case GUARD_INTERVAL_1_4:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003803 transmissionParams |=
3804 OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003805 break;
3806 case GUARD_INTERVAL_1_32:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003807 transmissionParams |=
3808 OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003809 break;
3810 case GUARD_INTERVAL_1_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003811 transmissionParams |=
3812 OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003813 break;
3814 case GUARD_INTERVAL_1_8:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003815 transmissionParams |=
3816 OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003817 break;
3818 }
3819
3820 /* hierarchy */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003821 switch (state->param.u.ofdm.hierarchy_information) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003822 case HIERARCHY_AUTO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003823 case HIERARCHY_NONE:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003824 default:
3825 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3826 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003827 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3828 /* break; */
3829 case HIERARCHY_1:
3830 transmissionParams |=
3831 OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003832 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003833 case HIERARCHY_2:
3834 transmissionParams |=
3835 OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003836 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003837 case HIERARCHY_4:
3838 transmissionParams |=
3839 OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003840 break;
3841 }
3842
3843
3844 /* constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003845 switch (state->param.u.ofdm.constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003846 case QAM_AUTO:
3847 default:
3848 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3849 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3850 case QAM_64:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003851 transmissionParams |=
3852 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003853 break;
3854 case QPSK:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003855 transmissionParams |=
3856 OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003857 break;
3858 case QAM_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003859 transmissionParams |=
3860 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003861 break;
3862 }
3863#if 0
Oliver Endrissebc7de22011-07-03 13:49:44 -03003864 /* No hierachical channels support in BDA */
3865 /* Priority (only for hierarchical channels) */
3866 switch (channel->priority) {
3867 case DRX_PRIORITY_LOW:
3868 transmissionParams |=
3869 OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3870 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3871 OFDM_EC_SB_PRIOR_LO);
3872 break;
3873 case DRX_PRIORITY_HIGH:
3874 transmissionParams |=
3875 OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3876 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3877 OFDM_EC_SB_PRIOR_HI));
3878 break;
3879 case DRX_PRIORITY_UNKNOWN: /* fall through */
3880 default:
3881 return DRX_STS_INVALID_ARG;
3882 break;
3883 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003884#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03003885 /* Set Priorty high */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003886 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003887 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003888 if (status < 0)
3889 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003890#endif
3891
3892 /* coderate */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003893 switch (state->param.u.ofdm.code_rate_HP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003894 case FEC_AUTO:
3895 default:
3896 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3897 /* fall through , try first guess DRX_CODERATE_2DIV3 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003898 case FEC_2_3:
3899 transmissionParams |=
3900 OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003901 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003902 case FEC_1_2:
3903 transmissionParams |=
3904 OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003905 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003906 case FEC_3_4:
3907 transmissionParams |=
3908 OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003909 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003910 case FEC_5_6:
3911 transmissionParams |=
3912 OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003913 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003914 case FEC_7_8:
3915 transmissionParams |=
3916 OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003917 break;
3918 }
3919
3920 /* SAW filter selection: normaly not necesarry, but if wanted
3921 the application can select a SAW filter via the driver by using UIOs */
3922 /* First determine real bandwidth (Hz) */
3923 /* Also set delay for impulse noise cruncher */
3924 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3925 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3926 functions */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003927 switch (state->param.u.ofdm.bandwidth) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003928 case BANDWIDTH_AUTO:
3929 case BANDWIDTH_8_MHZ:
3930 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003931 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003932 if (status < 0)
3933 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003934 /* cochannel protection for PAL 8 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003935 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003936 if (status < 0)
3937 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003938 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003939 if (status < 0)
3940 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003941 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003942 if (status < 0)
3943 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003944 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003945 if (status < 0)
3946 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003947 break;
3948 case BANDWIDTH_7_MHZ:
3949 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003950 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003951 if (status < 0)
3952 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003953 /* cochannel protection for PAL 7 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003954 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003955 if (status < 0)
3956 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003957 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003958 if (status < 0)
3959 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003960 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003961 if (status < 0)
3962 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003963 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003964 if (status < 0)
3965 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003966 break;
3967 case BANDWIDTH_6_MHZ:
3968 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003969 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003970 if (status < 0)
3971 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003972 /* cochannel protection for NTSC 6 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003973 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003974 if (status < 0)
3975 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003976 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003977 if (status < 0)
3978 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003979 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003980 if (status < 0)
3981 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003982 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003983 if (status < 0)
3984 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003985 break;
Mauro Carvalho Chehabe16cede2011-07-03 18:18:14 -03003986 default:
3987 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003988 }
3989
Oliver Endrissebc7de22011-07-03 13:49:44 -03003990 if (iqmRcRateOfs == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003991 /* Now compute IQM_RC_RATE_OFS
3992 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3993 =>
3994 ((SysFreq / BandWidth) * (2^21)) - (2^23)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003995 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003996 /* (SysFreq / BandWidth) * (2^28) */
3997 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
3998 => assert(MAX(sysClk) < 16*MIN(bandwidth))
3999 => assert(109714272 > 48000000) = true so Frac 28 can be used */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004000 iqmRcRateOfs = Frac28a((u32)
4001 ((state->m_sysClockFreq *
4002 1000) / 3), bandwidth);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004003 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4004 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004005 iqmRcRateOfs += 0x80L;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004006 iqmRcRateOfs = iqmRcRateOfs >> 7;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004007 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004008 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004009 }
4010
Oliver Endrissebc7de22011-07-03 13:49:44 -03004011 iqmRcRateOfs &=
4012 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4013 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004014 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004015 if (status < 0)
4016 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004017
4018 /* Bandwidth setting done */
4019
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004020#if 0
4021 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4022 if (status < 0)
4023 break;
4024#endif
4025 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4026 if (status < 0)
4027 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004028
4029 /*== Start SC, write channel settings to SC ===============================*/
4030
4031 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004032 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004033 if (status < 0)
4034 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004035
4036 /* Enable SC after setting all other parameters */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004037 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004038 if (status < 0)
4039 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004040 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004041 if (status < 0)
4042 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004043
4044
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004045 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4046 if (status < 0)
4047 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004048
4049 /* Write SC parameter registers, set all AUTO flags in operation mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004050 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4051 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4052 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4053 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4054 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4055 status =
4056 DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4057 0, transmissionParams, param1, 0, 0, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004058 if (!state->m_DRXK_A3_ROM_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004059 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4060 if (status < 0)
4061 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004062
Oliver Endrissebc7de22011-07-03 13:49:44 -03004063 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004064
4065 return status;
4066}
4067
4068
4069/*============================================================================*/
4070
4071/**
4072* \brief Retreive lock status .
4073* \param demod Pointer to demodulator instance.
4074* \param lockStat Pointer to lock status structure.
4075* \return DRXStatus_t.
4076*
4077*/
4078static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4079{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004080 int status;
4081 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4082 OFDM_SC_RA_RAM_LOCK_FEC__M);
4083 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4084 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004085
Oliver Endrissebc7de22011-07-03 13:49:44 -03004086 u16 ScRaRamLock = 0;
4087 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004088
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004089 dprintk(1, "\n");
4090
Oliver Endrissebc7de22011-07-03 13:49:44 -03004091 /* driver 0.9.0 */
4092 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004093 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004094 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP) {
4095 /* SC not active; return DRX_NOT_LOCKED */
4096 *pLockStatus = NOT_LOCKED;
4097 return status;
4098 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004099
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004100 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004101
Oliver Endrissebc7de22011-07-03 13:49:44 -03004102 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4103 *pLockStatus = MPEG_LOCK;
4104 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4105 *pLockStatus = FEC_LOCK;
4106 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4107 *pLockStatus = DEMOD_LOCK;
4108 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4109 *pLockStatus = NEVER_LOCK;
4110 else
4111 *pLockStatus = NOT_LOCKED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004112
Oliver Endrissebc7de22011-07-03 13:49:44 -03004113 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004114}
4115
Oliver Endrissebc7de22011-07-03 13:49:44 -03004116static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004117{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004118 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
4119 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004120
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004121 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004122 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004123 status = CtrlPowerMode(state, &powerMode);
4124 if (status < 0)
4125 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004126
Oliver Endrissebc7de22011-07-03 13:49:44 -03004127 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004128
Oliver Endrissebc7de22011-07-03 13:49:44 -03004129 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004130}
4131
4132
Oliver Endrissebc7de22011-07-03 13:49:44 -03004133/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004134static int PowerDownQAM(struct drxk_state *state)
4135{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004136 u16 data = 0;
4137 u16 cmdResult;
4138 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004139
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004140 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004141 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004142 status = read16(state, SCU_COMM_EXEC__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004143 if (status < 0)
4144 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004145 if (data == SCU_COMM_EXEC_ACTIVE) {
4146 /*
4147 STOP demodulator
4148 QAM and HW blocks
4149 */
4150 /* stop all comstate->m_exec */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004151 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004152 if (status < 0)
4153 break;
4154 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
4155 if (status < 0)
4156 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004157 }
4158 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004159 status = SetIqmAf(state, false);
4160 if (status < 0)
4161 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004162 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004163
Oliver Endrissebc7de22011-07-03 13:49:44 -03004164 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004165}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004166
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004167/*============================================================================*/
4168
4169/**
4170* \brief Setup of the QAM Measurement intervals for signal quality
4171* \param demod instance of demod.
4172* \param constellation current constellation.
4173* \return DRXStatus_t.
4174*
4175* NOTE:
4176* Take into account that for certain settings the errorcounters can overflow.
4177* The implementation does not check this.
4178*
4179*/
4180static int SetQAMMeasurement(struct drxk_state *state,
4181 enum EDrxkConstellation constellation,
4182 u32 symbolRate)
4183{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004184 u32 fecBitsDesired = 0; /* BER accounting period */
4185 u32 fecRsPeriodTotal = 0; /* Total period */
4186 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4187 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004188 int status = 0;
4189
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004190 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004191
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004192 fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004193 do {
4194
4195 /* fecBitsDesired = symbolRate [kHz] *
4196 FrameLenght [ms] *
4197 (constellation + 1) *
4198 SyncLoss (== 1) *
4199 ViterbiLoss (==1)
Oliver Endrissebc7de22011-07-03 13:49:44 -03004200 */
4201 switch (constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004202 case DRX_CONSTELLATION_QAM16:
4203 fecBitsDesired = 4 * symbolRate;
4204 break;
4205 case DRX_CONSTELLATION_QAM32:
4206 fecBitsDesired = 5 * symbolRate;
4207 break;
4208 case DRX_CONSTELLATION_QAM64:
4209 fecBitsDesired = 6 * symbolRate;
4210 break;
4211 case DRX_CONSTELLATION_QAM128:
4212 fecBitsDesired = 7 * symbolRate;
4213 break;
4214 case DRX_CONSTELLATION_QAM256:
4215 fecBitsDesired = 8 * symbolRate;
4216 break;
4217 default:
4218 status = -EINVAL;
4219 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004220 status = status;
4221 if (status < 0)
4222 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004223
Oliver Endrissebc7de22011-07-03 13:49:44 -03004224 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4225 fecBitsDesired *= 500; /* meas. period [ms] */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004226
4227 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4228 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004229 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004230
4231 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4232 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4233 if (fecRsPrescale == 0) {
4234 /* Divide by zero (though impossible) */
4235 status = -1;
4236 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004237 status = status;
4238 if (status < 0)
4239 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004240 fecRsPeriod =
4241 ((u16) fecRsPeriodTotal +
4242 (fecRsPrescale >> 1)) / fecRsPrescale;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004243
4244 /* write corresponding registers */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004245 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004246 if (status < 0)
4247 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004248 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004249 if (status < 0)
4250 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004251 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004252 if (status < 0)
4253 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004254
4255 } while (0);
4256
Oliver Endrissebc7de22011-07-03 13:49:44 -03004257 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03004258 printk(KERN_ERR "drxk: %s: status - %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004259
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004260 return status;
4261}
4262
Oliver Endrissebc7de22011-07-03 13:49:44 -03004263static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004264{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004265 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004266
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004267 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004268 do {
4269 /* QAM Equalizer Setup */
4270 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004271 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004272 if (status < 0)
4273 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004274 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004275 if (status < 0)
4276 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004277 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004278 if (status < 0)
4279 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004280 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004281 if (status < 0)
4282 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004283 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004284 if (status < 0)
4285 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004286 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004287 if (status < 0)
4288 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004289 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004290 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004291 if (status < 0)
4292 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004293 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004294 if (status < 0)
4295 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004296 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004297 if (status < 0)
4298 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004299 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004300 if (status < 0)
4301 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004302 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004303 if (status < 0)
4304 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004305 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004306 if (status < 0)
4307 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004308
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004309 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004310 if (status < 0)
4311 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004312 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004313 if (status < 0)
4314 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004315 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004316 if (status < 0)
4317 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004318
Oliver Endrissebc7de22011-07-03 13:49:44 -03004319 /* QAM Slicer Settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004320 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004321 if (status < 0)
4322 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004323
Oliver Endrissebc7de22011-07-03 13:49:44 -03004324 /* QAM Loop Controller Coeficients */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004325 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004326 if (status < 0)
4327 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004328 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004329 if (status < 0)
4330 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004331 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004332 if (status < 0)
4333 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004334 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004335 if (status < 0)
4336 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004337 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004338 if (status < 0)
4339 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004340 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004341 if (status < 0)
4342 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004343 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004344 if (status < 0)
4345 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004346 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004347 if (status < 0)
4348 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004349
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004350 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004351 if (status < 0)
4352 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004353 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004354 if (status < 0)
4355 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004356 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004357 if (status < 0)
4358 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004359 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004360 if (status < 0)
4361 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004362 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004363 if (status < 0)
4364 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004365 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004366 if (status < 0)
4367 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004368 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004369 if (status < 0)
4370 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004371 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004372 if (status < 0)
4373 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004374 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004375 if (status < 0)
4376 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004377 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004378 if (status < 0)
4379 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004380 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004381 if (status < 0)
4382 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004383 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004384 if (status < 0)
4385 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004386
4387
Oliver Endrissebc7de22011-07-03 13:49:44 -03004388 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004389
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004390 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004391 if (status < 0)
4392 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004393 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004394 if (status < 0)
4395 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004396 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004397 if (status < 0)
4398 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004399 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004400 if (status < 0)
4401 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004402 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004403 if (status < 0)
4404 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004405 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004406 if (status < 0)
4407 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004408
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004409 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004410 if (status < 0)
4411 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004412 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004413 if (status < 0)
4414 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004415 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004416 if (status < 0)
4417 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004418
4419
Oliver Endrissebc7de22011-07-03 13:49:44 -03004420 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004421
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004422 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004423 if (status < 0)
4424 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004425 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004426 if (status < 0)
4427 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004428 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004429 if (status < 0)
4430 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004431 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004432 if (status < 0)
4433 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004434 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004435 if (status < 0)
4436 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004437 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004438 if (status < 0)
4439 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004440 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004441 if (status < 0)
4442 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004443 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004444
Oliver Endrissebc7de22011-07-03 13:49:44 -03004445 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004446}
4447
4448/*============================================================================*/
4449
4450/**
4451* \brief QAM32 specific setup
4452* \param demod instance of demod.
4453* \return DRXStatus_t.
4454*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004455static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004456{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004457 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004458
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004459 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004460 do {
4461 /* QAM Equalizer Setup */
4462 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004463 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004464 if (status < 0)
4465 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004466 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004467 if (status < 0)
4468 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004469 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004470 if (status < 0)
4471 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004472 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004473 if (status < 0)
4474 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004475 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004476 if (status < 0)
4477 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004478 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004479 if (status < 0)
4480 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004481
Oliver Endrissebc7de22011-07-03 13:49:44 -03004482 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004483 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004484 if (status < 0)
4485 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004486 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004487 if (status < 0)
4488 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004489 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004490 if (status < 0)
4491 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004492 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004493 if (status < 0)
4494 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004495 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004496 if (status < 0)
4497 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004498 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004499 if (status < 0)
4500 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004501
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004502 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004503 if (status < 0)
4504 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004505 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004506 if (status < 0)
4507 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004508 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004509 if (status < 0)
4510 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004511
Oliver Endrissebc7de22011-07-03 13:49:44 -03004512 /* QAM Slicer Settings */
4513
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004514 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004515 if (status < 0)
4516 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004517
4518
Oliver Endrissebc7de22011-07-03 13:49:44 -03004519 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004520
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004521 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004522 if (status < 0)
4523 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004524 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004525 if (status < 0)
4526 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004527 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004528 if (status < 0)
4529 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004530 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004531 if (status < 0)
4532 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004533 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004534 if (status < 0)
4535 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004536 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004537 if (status < 0)
4538 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004539 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004540 if (status < 0)
4541 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004542 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004543 if (status < 0)
4544 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004545
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004546 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004547 if (status < 0)
4548 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004549 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004550 if (status < 0)
4551 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004552 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004553 if (status < 0)
4554 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004555 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004556 if (status < 0)
4557 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004558 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004559 if (status < 0)
4560 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004561 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004562 if (status < 0)
4563 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004564 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004565 if (status < 0)
4566 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004567 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004568 if (status < 0)
4569 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004570 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004571 if (status < 0)
4572 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004573 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004574 if (status < 0)
4575 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004576 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004577 if (status < 0)
4578 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004579 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004580 if (status < 0)
4581 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004582
4583
Oliver Endrissebc7de22011-07-03 13:49:44 -03004584 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004585
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004586 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004587 if (status < 0)
4588 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004589 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004590 if (status < 0)
4591 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004592 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004593 if (status < 0)
4594 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004595 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004596 if (status < 0)
4597 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004598 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004599 if (status < 0)
4600 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004601 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004602 if (status < 0)
4603 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004604
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004605 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004606 if (status < 0)
4607 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004608 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004609 if (status < 0)
4610 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004611 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004612 if (status < 0)
4613 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004614
4615
Oliver Endrissebc7de22011-07-03 13:49:44 -03004616 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004617
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004618 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004619 if (status < 0)
4620 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004621 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004622 if (status < 0)
4623 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004624 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004625 if (status < 0)
4626 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004627 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004628 if (status < 0)
4629 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004630 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004631 if (status < 0)
4632 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004633 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004634 if (status < 0)
4635 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004636 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004637 if (status < 0)
4638 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004639 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004640
Oliver Endrissebc7de22011-07-03 13:49:44 -03004641 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004642}
4643
4644/*============================================================================*/
4645
4646/**
4647* \brief QAM64 specific setup
4648* \param demod instance of demod.
4649* \return DRXStatus_t.
4650*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004651static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004652{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004653 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004654
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004655 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004656 do {
4657 /* QAM Equalizer Setup */
4658 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004659 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004660 if (status < 0)
4661 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004662 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004663 if (status < 0)
4664 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004665 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004666 if (status < 0)
4667 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004668 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004669 if (status < 0)
4670 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004671 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004672 if (status < 0)
4673 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004674 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004675 if (status < 0)
4676 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004677
Oliver Endrissebc7de22011-07-03 13:49:44 -03004678 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004679 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004680 if (status < 0)
4681 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004682 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004683 if (status < 0)
4684 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004685 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004686 if (status < 0)
4687 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004688 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004689 if (status < 0)
4690 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004691 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004692 if (status < 0)
4693 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004694 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004695 if (status < 0)
4696 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004697
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004698 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004699 if (status < 0)
4700 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004701 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004702 if (status < 0)
4703 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004704 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004705 if (status < 0)
4706 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004707
4708 /* QAM Slicer Settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004709 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004710 if (status < 0)
4711 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004712
4713
Oliver Endrissebc7de22011-07-03 13:49:44 -03004714 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004715
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004716 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004717 if (status < 0)
4718 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004719 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004720 if (status < 0)
4721 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004722 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004723 if (status < 0)
4724 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004725 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004726 if (status < 0)
4727 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004728 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004729 if (status < 0)
4730 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004731 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004732 if (status < 0)
4733 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004734 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004735 if (status < 0)
4736 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004737 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004738 if (status < 0)
4739 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004740
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004741 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004742 if (status < 0)
4743 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004744 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004745 if (status < 0)
4746 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004747 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004748 if (status < 0)
4749 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004750 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004751 if (status < 0)
4752 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004753 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004754 if (status < 0)
4755 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004756 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004757 if (status < 0)
4758 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004759 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004760 if (status < 0)
4761 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004762 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004763 if (status < 0)
4764 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004765 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004766 if (status < 0)
4767 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004768 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004769 if (status < 0)
4770 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004771 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004772 if (status < 0)
4773 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004774 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004775 if (status < 0)
4776 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004777
4778
Oliver Endrissebc7de22011-07-03 13:49:44 -03004779 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004780
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004781 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004782 if (status < 0)
4783 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004784 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004785 if (status < 0)
4786 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004787 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004788 if (status < 0)
4789 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004790 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004791 if (status < 0)
4792 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004793 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004794 if (status < 0)
4795 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004796 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004797 if (status < 0)
4798 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004799
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004800 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004801 if (status < 0)
4802 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004803 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004804 if (status < 0)
4805 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004806 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004807 if (status < 0)
4808 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004809
4810
Oliver Endrissebc7de22011-07-03 13:49:44 -03004811 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004812
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004813 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004814 if (status < 0)
4815 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004816 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004817 if (status < 0)
4818 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004819 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004820 if (status < 0)
4821 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004822 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004823 if (status < 0)
4824 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004825 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004826 if (status < 0)
4827 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004828 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004829 if (status < 0)
4830 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004831 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004832 if (status < 0)
4833 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004834 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004835
Oliver Endrissebc7de22011-07-03 13:49:44 -03004836 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004837}
4838
4839/*============================================================================*/
4840
4841/**
4842* \brief QAM128 specific setup
4843* \param demod: instance of demod.
4844* \return DRXStatus_t.
4845*/
4846static int SetQAM128(struct drxk_state *state)
4847{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004848 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004849
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004850 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004851 do {
4852 /* QAM Equalizer Setup */
4853 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004854 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004855 if (status < 0)
4856 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004857 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004858 if (status < 0)
4859 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004860 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004861 if (status < 0)
4862 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004863 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004864 if (status < 0)
4865 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004866 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004867 if (status < 0)
4868 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004869 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004870 if (status < 0)
4871 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004872
Oliver Endrissebc7de22011-07-03 13:49:44 -03004873 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004874 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004875 if (status < 0)
4876 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004877 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004878 if (status < 0)
4879 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004880 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004881 if (status < 0)
4882 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004883 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004884 if (status < 0)
4885 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004886 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004887 if (status < 0)
4888 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004889 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004890 if (status < 0)
4891 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004892
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004893 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004894 if (status < 0)
4895 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004896 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004897 if (status < 0)
4898 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004899 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004900 if (status < 0)
4901 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004902
4903
Oliver Endrissebc7de22011-07-03 13:49:44 -03004904 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004905
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004906 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004907 if (status < 0)
4908 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004909
4910
Oliver Endrissebc7de22011-07-03 13:49:44 -03004911 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004912
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004913 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004914 if (status < 0)
4915 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004916 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004917 if (status < 0)
4918 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004919 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004920 if (status < 0)
4921 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004922 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004923 if (status < 0)
4924 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004925 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004926 if (status < 0)
4927 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004928 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004929 if (status < 0)
4930 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004931 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004932 if (status < 0)
4933 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004934 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004935 if (status < 0)
4936 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004937
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004938 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004939 if (status < 0)
4940 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004941 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004942 if (status < 0)
4943 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004944 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004945 if (status < 0)
4946 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004947 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004948 if (status < 0)
4949 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004950 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004951 if (status < 0)
4952 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004953 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004954 if (status < 0)
4955 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004956 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004957 if (status < 0)
4958 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004959 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004960 if (status < 0)
4961 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004962 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004963 if (status < 0)
4964 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004965 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004966 if (status < 0)
4967 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004968 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004969 if (status < 0)
4970 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004971 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004972 if (status < 0)
4973 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004974
4975
Oliver Endrissebc7de22011-07-03 13:49:44 -03004976 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004977
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004978 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004979 if (status < 0)
4980 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004981 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004982 if (status < 0)
4983 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004984 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004985 if (status < 0)
4986 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004987 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004988 if (status < 0)
4989 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004990 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004991 if (status < 0)
4992 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004993 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004994 if (status < 0)
4995 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004996
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004997 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004998 if (status < 0)
4999 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005000 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005001 if (status < 0)
5002 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005003
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005004 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005005 if (status < 0)
5006 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005007
Oliver Endrissebc7de22011-07-03 13:49:44 -03005008 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005009
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005010 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005011 if (status < 0)
5012 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005013 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005014 if (status < 0)
5015 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005016 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005017 if (status < 0)
5018 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005019 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005020 if (status < 0)
5021 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005022 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005023 if (status < 0)
5024 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005025 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005026 if (status < 0)
5027 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005028 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005029 if (status < 0)
5030 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005031 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005032
Oliver Endrissebc7de22011-07-03 13:49:44 -03005033 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005034}
5035
5036/*============================================================================*/
5037
5038/**
5039* \brief QAM256 specific setup
5040* \param demod: instance of demod.
5041* \return DRXStatus_t.
5042*/
5043static int SetQAM256(struct drxk_state *state)
5044{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005045 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005046
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005047 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005048 do {
5049 /* QAM Equalizer Setup */
5050 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005051 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005052 if (status < 0)
5053 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005054 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005055 if (status < 0)
5056 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005057 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005058 if (status < 0)
5059 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005060 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005061 if (status < 0)
5062 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005063 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005064 if (status < 0)
5065 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005066 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005067 if (status < 0)
5068 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005069
Oliver Endrissebc7de22011-07-03 13:49:44 -03005070 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005071 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005072 if (status < 0)
5073 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005074 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005075 if (status < 0)
5076 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005077 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005078 if (status < 0)
5079 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005080 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005081 if (status < 0)
5082 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005083 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005084 if (status < 0)
5085 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005086 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005087 if (status < 0)
5088 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005089
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005090 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005091 if (status < 0)
5092 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005093 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005094 if (status < 0)
5095 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005096 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005097 if (status < 0)
5098 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005099
Oliver Endrissebc7de22011-07-03 13:49:44 -03005100 /* QAM Slicer Settings */
5101
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005102 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005103 if (status < 0)
5104 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005105
5106
Oliver Endrissebc7de22011-07-03 13:49:44 -03005107 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005108
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005109 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005110 if (status < 0)
5111 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005112 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005113 if (status < 0)
5114 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005115 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005116 if (status < 0)
5117 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005118 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005119 if (status < 0)
5120 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005121 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005122 if (status < 0)
5123 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005124 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005125 if (status < 0)
5126 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005127 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005128 if (status < 0)
5129 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005130 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005131 if (status < 0)
5132 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005133
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005134 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005135 if (status < 0)
5136 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005137 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005138 if (status < 0)
5139 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005140 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005141 if (status < 0)
5142 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005143 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005144 if (status < 0)
5145 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005146 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005147 if (status < 0)
5148 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005149 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005150 if (status < 0)
5151 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005152 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005153 if (status < 0)
5154 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005155 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005156 if (status < 0)
5157 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005158 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005159 if (status < 0)
5160 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005161 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005162 if (status < 0)
5163 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005164 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005165 if (status < 0)
5166 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005167 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005168 if (status < 0)
5169 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005170
5171
Oliver Endrissebc7de22011-07-03 13:49:44 -03005172 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005173
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005174 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005175 if (status < 0)
5176 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005177 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005178 if (status < 0)
5179 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005180 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005181 if (status < 0)
5182 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005183 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005184 if (status < 0)
5185 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005186 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005187 if (status < 0)
5188 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005189 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005190 if (status < 0)
5191 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005192
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005193 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005194 if (status < 0)
5195 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005196 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005197 if (status < 0)
5198 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005199 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005200 if (status < 0)
5201 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005202
5203
Oliver Endrissebc7de22011-07-03 13:49:44 -03005204 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005205
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005206 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005207 if (status < 0)
5208 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005209 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005210 if (status < 0)
5211 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005212 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005213 if (status < 0)
5214 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005215 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005216 if (status < 0)
5217 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005218 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005219 if (status < 0)
5220 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005221 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005222 if (status < 0)
5223 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005224 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005225 if (status < 0)
5226 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005227 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005228
Oliver Endrissebc7de22011-07-03 13:49:44 -03005229 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005230}
5231
5232
5233/*============================================================================*/
5234/**
5235* \brief Reset QAM block.
5236* \param demod: instance of demod.
5237* \param channel: pointer to channel data.
5238* \return DRXStatus_t.
5239*/
5240static int QAMResetQAM(struct drxk_state *state)
5241{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005242 int status;
5243 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005244
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005245 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005246 do {
5247 /* Stop QAM comstate->m_exec */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005248 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005249 if (status < 0)
5250 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005251
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005252 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5253 if (status < 0)
5254 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005255 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005256
Oliver Endrissebc7de22011-07-03 13:49:44 -03005257 /* All done, all OK */
5258 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005259}
5260
5261/*============================================================================*/
5262
5263/**
5264* \brief Set QAM symbolrate.
5265* \param demod: instance of demod.
5266* \param channel: pointer to channel data.
5267* \return DRXStatus_t.
5268*/
5269static int QAMSetSymbolrate(struct drxk_state *state)
5270{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005271 u32 adcFrequency = 0;
5272 u32 symbFreq = 0;
5273 u32 iqmRcRate = 0;
5274 u16 ratesel = 0;
5275 u32 lcSymbRate = 0;
5276 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005277
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005278 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005279 do {
5280 /* Select & calculate correct IQM rate */
5281 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5282 ratesel = 0;
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005283 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005284 if (state->param.u.qam.symbol_rate <= 1188750)
5285 ratesel = 3;
5286 else if (state->param.u.qam.symbol_rate <= 2377500)
5287 ratesel = 2;
5288 else if (state->param.u.qam.symbol_rate <= 4755000)
5289 ratesel = 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005290 status = write16(state, IQM_FD_RATESEL__A, ratesel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005291 if (status < 0)
5292 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005293
Oliver Endrissebc7de22011-07-03 13:49:44 -03005294 /*
5295 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5296 */
5297 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5298 if (symbFreq == 0) {
5299 /* Divide by zero */
5300 return -1;
5301 }
5302 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5303 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5304 (1 << 23);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005305 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005306 if (status < 0)
5307 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005308 state->m_iqmRcRate = iqmRcRate;
5309 /*
5310 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5311 */
5312 symbFreq = state->param.u.qam.symbol_rate;
5313 if (adcFrequency == 0) {
5314 /* Divide by zero */
5315 return -1;
5316 }
5317 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5318 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5319 16);
5320 if (lcSymbRate > 511)
5321 lcSymbRate = 511;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005322 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005323 if (status < 0)
5324 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005325 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005326
Oliver Endrissebc7de22011-07-03 13:49:44 -03005327 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005328}
5329
5330/*============================================================================*/
5331
5332/**
5333* \brief Get QAM lock status.
5334* \param demod: instance of demod.
5335* \param channel: pointer to channel data.
5336* \return DRXStatus_t.
5337*/
5338
5339static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5340{
5341 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005342 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005343
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005344 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005345 status =
5346 scu_command(state,
5347 SCU_RAM_COMMAND_STANDARD_QAM |
5348 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5349 Result);
5350 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005351 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005352
5353 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005354 /* 0x0000 NOT LOCKED */
5355 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005356 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005357 /* 0x4000 DEMOD LOCKED */
5358 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005359 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005360 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5361 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005362 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005363 /* 0xC000 NEVER LOCKED */
5364 /* (system will never be able to lock to the signal) */
5365 /* TODO: check this, intermediate & standard specific lock states are not
5366 taken into account here */
5367 *pLockStatus = NEVER_LOCK;
5368 }
5369 return status;
5370}
5371
5372#define QAM_MIRROR__M 0x03
5373#define QAM_MIRROR_NORMAL 0x00
5374#define QAM_MIRRORED 0x01
5375#define QAM_MIRROR_AUTO_ON 0x02
5376#define QAM_LOCKRANGE__M 0x10
5377#define QAM_LOCKRANGE_NORMAL 0x10
5378
Oliver Endrissebc7de22011-07-03 13:49:44 -03005379static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5380 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005381{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005382 int status = 0;
5383 u8 parameterLen;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005384 u16 setEnvParameters[5];
5385 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5386 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005387
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005388 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005389 do {
5390 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005391 STEP 1: reset demodulator
5392 resets FEC DI and FEC RS
5393 resets QAM block
5394 resets SCU variables
5395 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005396 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005397 if (status < 0)
5398 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005399 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005400 if (status < 0)
5401 break;
5402 status = QAMResetQAM(state);
5403 if (status < 0)
5404 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005405
5406 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005407 STEP 2: configure demodulator
5408 -set env
5409 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5410 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005411 status = QAMSetSymbolrate(state);
5412 if (status < 0)
5413 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005414
5415 /* Env parameters */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005416 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005417 if (state->m_OperationMode == OM_QAM_ITU_C)
Oliver Endrissebc7de22011-07-03 13:49:44 -03005418 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005419 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005420 /* check for LOCKRANGE Extented */
5421 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005422 parameterLen = 4;
5423
5424 /* Set params */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005425 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005426 case QAM_256:
5427 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5428 break;
5429 case QAM_AUTO:
5430 case QAM_64:
5431 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5432 break;
5433 case QAM_16:
5434 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5435 break;
5436 case QAM_32:
5437 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5438 break;
5439 case QAM_128:
5440 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5441 break;
5442 default:
5443 status = -EINVAL;
5444 break;
5445 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005446 status = status;
5447 if (status < 0)
5448 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005449 setParamParameters[0] = state->m_Constellation; /* constellation */
5450 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005451
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005452 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5453 if (status < 0)
5454 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005455
5456
5457 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5458 setup constellation independent registers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005459#if 0
5460 status = SetFrequency (channel, tunerFreqOffset));
5461 if (status < 0)
5462 break;
5463#endif
5464 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5465 if (status < 0)
5466 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005467
5468 /* Setup BER measurement */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005469 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5470 if (status < 0)
5471 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005472
5473 /* Reset default values */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005474 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005475 if (status < 0)
5476 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005477 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005478 if (status < 0)
5479 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005480
Oliver Endrissebc7de22011-07-03 13:49:44 -03005481 /* Reset default LC values */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005482 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005483 if (status < 0)
5484 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005485 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005486 if (status < 0)
5487 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005488 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005489 if (status < 0)
5490 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005491 status = write16(state, QAM_LC_MODE__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005492 if (status < 0)
5493 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005494
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005495 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005496 if (status < 0)
5497 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005498 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005499 if (status < 0)
5500 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005501 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005502 if (status < 0)
5503 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005504 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005505 if (status < 0)
5506 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005507 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005508 if (status < 0)
5509 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005510 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005511 if (status < 0)
5512 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005513 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005514 if (status < 0)
5515 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005516 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005517 if (status < 0)
5518 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005519 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005520 if (status < 0)
5521 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005522 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005523 if (status < 0)
5524 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005525 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005526 if (status < 0)
5527 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005528 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005529 if (status < 0)
5530 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005531 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005532 if (status < 0)
5533 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005534 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005535 if (status < 0)
5536 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005537 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005538 if (status < 0)
5539 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005540
Oliver Endrissebc7de22011-07-03 13:49:44 -03005541 /* Mirroring, QAM-block starting point not inverted */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005542 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005543 if (status < 0)
5544 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005545
Oliver Endrissebc7de22011-07-03 13:49:44 -03005546 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005547 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005548 if (status < 0)
5549 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005550
Oliver Endrissebc7de22011-07-03 13:49:44 -03005551 /* STEP 4: constellation specific setup */
5552 switch (state->param.u.qam.modulation) {
5553 case QAM_16:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005554 status = SetQAM16(state);
5555 if (status < 0)
5556 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005557 break;
5558 case QAM_32:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005559 status = SetQAM32(state);
5560 if (status < 0)
5561 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005562 break;
5563 case QAM_AUTO:
5564 case QAM_64:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005565 status = SetQAM64(state);
5566 if (status < 0)
5567 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005568 break;
5569 case QAM_128:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005570 status = SetQAM128(state);
5571 if (status < 0)
5572 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005573 break;
5574 case QAM_256:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005575 status = SetQAM256(state);
5576 if (status < 0)
5577 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005578 break;
5579 default:
5580 return -1;
5581 break;
5582 } /* switch */
5583 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005584 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005585 if (status < 0)
5586 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005587
5588
Oliver Endrissebc7de22011-07-03 13:49:44 -03005589 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5590 /* extAttr->currentChannel.constellation = channel->constellation; */
5591 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005592 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5593 if (status < 0)
5594 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005595
Oliver Endrissebc7de22011-07-03 13:49:44 -03005596 /* Start processes */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005597 status = MPEGTSStart(state);
5598 if (status < 0)
5599 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005600 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005601 if (status < 0)
5602 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005603 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005604 if (status < 0)
5605 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005606 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005607 if (status < 0)
5608 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005609
Oliver Endrissebc7de22011-07-03 13:49:44 -03005610 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005611 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5612 if (status < 0)
5613 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005614
Oliver Endrissebc7de22011-07-03 13:49:44 -03005615 /* update global DRXK data container */
5616 /*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005617
Oliver Endrissebc7de22011-07-03 13:49:44 -03005618 /* All done, all OK */
5619 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005620
Oliver Endrissebc7de22011-07-03 13:49:44 -03005621 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005622 printk(KERN_ERR "drxk: %s %d\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005623
5624 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005625}
5626
Oliver Endrissebc7de22011-07-03 13:49:44 -03005627static int SetQAMStandard(struct drxk_state *state,
5628 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005629{
5630#ifdef DRXK_QAM_TAPS
5631#define DRXK_QAMA_TAPS_SELECT
5632#include "drxk_filters.h"
5633#undef DRXK_QAMA_TAPS_SELECT
5634#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03005635 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005636#endif
5637
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005638 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005639 do {
5640 /* added antenna switch */
5641 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005642
Oliver Endrissebc7de22011-07-03 13:49:44 -03005643 /* Ensure correct power-up mode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005644 status = PowerUpQAM(state);
5645 if (status < 0)
5646 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005647 /* Reset QAM block */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005648 status = QAMResetQAM(state);
5649 if (status < 0)
5650 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005651
Oliver Endrissebc7de22011-07-03 13:49:44 -03005652 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005653
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005654 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005655 if (status < 0)
5656 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005657 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005658 if (status < 0)
5659 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005660
Oliver Endrissebc7de22011-07-03 13:49:44 -03005661 /* Upload IQM Channel Filter settings by
5662 boot loader from ROM table */
5663 switch (oMode) {
5664 case OM_QAM_ITU_A:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005665 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5666 if (status < 0)
5667 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005668 break;
5669 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005670 status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5671 if (status < 0)
5672 break;
5673 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5674 if (status < 0)
5675 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005676 break;
5677 default:
5678 status = -EINVAL;
5679 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005680 status = status;
5681 if (status < 0)
5682 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005683
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005684 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005685 if (status < 0)
5686 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005687 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005688 if (status < 0)
5689 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005690 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 -03005691 if (status < 0)
5692 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005693
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005694 status = write16(state, IQM_RC_STRETCH__A, 21);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005695 if (status < 0)
5696 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005697 status = write16(state, IQM_AF_CLP_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005698 if (status < 0)
5699 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005700 status = write16(state, IQM_AF_CLP_TH__A, 448);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005701 if (status < 0)
5702 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005703 status = write16(state, IQM_AF_SNS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005704 if (status < 0)
5705 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005706 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005707 if (status < 0)
5708 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005709
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005710 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005711 if (status < 0)
5712 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005713 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005714 if (status < 0)
5715 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005716 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005717 if (status < 0)
5718 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005719 status = write16(state, IQM_AF_UPD_SEL__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005720 if (status < 0)
5721 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005722
Oliver Endrissebc7de22011-07-03 13:49:44 -03005723 /* IQM Impulse Noise Processing Unit */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005724 status = write16(state, IQM_CF_CLP_VAL__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005725 if (status < 0)
5726 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005727 status = write16(state, IQM_CF_DATATH__A, 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005728 if (status < 0)
5729 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005730 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005731 if (status < 0)
5732 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005733 status = write16(state, IQM_CF_DET_LCT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005734 if (status < 0)
5735 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005736 status = write16(state, IQM_CF_WND_LEN__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005737 if (status < 0)
5738 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005739 status = write16(state, IQM_CF_PKDTH__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005740 if (status < 0)
5741 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005742 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005743 if (status < 0)
5744 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005745
Oliver Endrissebc7de22011-07-03 13:49:44 -03005746 /* turn on IQMAF. Must be done before setAgc**() */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005747 status = SetIqmAf(state, true);
5748 if (status < 0)
5749 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005750 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005751 if (status < 0)
5752 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005753
Oliver Endrissebc7de22011-07-03 13:49:44 -03005754 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005755 status = ADCSynchronization(state);
5756 if (status < 0)
5757 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005758
Oliver Endrissebc7de22011-07-03 13:49:44 -03005759 /* Set the FSM step period */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005760 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005761 if (status < 0)
5762 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005763
Oliver Endrissebc7de22011-07-03 13:49:44 -03005764 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005765 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005766 if (status < 0)
5767 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005768
Oliver Endrissebc7de22011-07-03 13:49:44 -03005769 /* No more resets of the IQM, current standard correctly set =>
5770 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005771
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005772 status = InitAGC(state, true);
5773 if (status < 0)
5774 break;
5775 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5776 if (status < 0)
5777 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005778
Oliver Endrissebc7de22011-07-03 13:49:44 -03005779 /* Configure AGC's */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005780 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5781 if (status < 0)
5782 break;
5783 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5784 if (status < 0)
5785 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005786
Oliver Endrissebc7de22011-07-03 13:49:44 -03005787 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005788 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005789 if (status < 0)
5790 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005791 } while (0);
5792 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005793}
5794
5795static int WriteGPIO(struct drxk_state *state)
5796{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005797 int status;
5798 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005799
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005800 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005801 do {
5802 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005803 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005804 if (status < 0)
5805 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005806
Oliver Endrissebc7de22011-07-03 13:49:44 -03005807 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005808 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005809 if (status < 0)
5810 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005811
Oliver Endrissebc7de22011-07-03 13:49:44 -03005812 if (state->m_hasSAWSW) {
5813 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005814 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005815 if (status < 0)
5816 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005817
Oliver Endrissebc7de22011-07-03 13:49:44 -03005818 /* use corresponding bit in io data output registar */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005819 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005820 if (status < 0)
5821 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005822 if (state->m_GPIO == 0)
5823 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5824 else
5825 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5826 /* write back to io data output register */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005827 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005828 if (status < 0)
5829 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005830
Oliver Endrissebc7de22011-07-03 13:49:44 -03005831 }
5832 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005833 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005834 if (status < 0)
5835 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005836 } while (0);
5837 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005838}
5839
5840static int SwitchAntennaToQAM(struct drxk_state *state)
5841{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005842 int status = -1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005843
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005844 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005845 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5846 if (state->m_GPIO != state->m_AntennaDVBC) {
5847 state->m_GPIO = state->m_AntennaDVBC;
5848 status = WriteGPIO(state);
5849 }
5850 }
5851 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005852}
5853
5854static int SwitchAntennaToDVBT(struct drxk_state *state)
5855{
5856 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005857
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005858 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005859 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5860 if (state->m_GPIO != state->m_AntennaDVBT) {
5861 state->m_GPIO = state->m_AntennaDVBT;
5862 status = WriteGPIO(state);
5863 }
5864 }
5865 return status;
5866}
5867
5868
5869static int PowerDownDevice(struct drxk_state *state)
5870{
5871 /* Power down to requested mode */
5872 /* Backup some register settings */
5873 /* Set pins with possible pull-ups connected to them in input mode */
5874 /* Analog power down */
5875 /* ADC power down */
5876 /* Power down device */
5877 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005878
5879 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005880 do {
5881 if (state->m_bPDownOpenBridge) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03005882 /* Open I2C bridge before power down of DRXK */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005883 status = ConfigureI2CBridge(state, true);
5884 if (status < 0)
5885 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005886 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005887 /* driver 0.9.0 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005888 status = DVBTEnableOFDMTokenRing(state, false);
5889 if (status < 0)
5890 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005891
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005892 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005893 if (status < 0)
5894 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005895 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005896 if (status < 0)
5897 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005898 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005899 status = HI_CfgCommand(state);
5900 if (status < 0)
5901 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005902 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005903
Oliver Endrissebc7de22011-07-03 13:49:44 -03005904 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005905 return -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005906
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005907 return 0;
5908}
5909
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005910static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005911{
5912 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005913 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005914
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005915 dprintk(1, "\n");
5916
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005917 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5918 if (err < 0) {
5919 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005920 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005921 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005922 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005923 return err;
5924 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005925 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005926 release_firmware(fw);
5927 return err;
5928}
5929
5930static int init_drxk(struct drxk_state *state)
5931{
5932 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005933 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005934 u16 driverVersion;
5935
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005936 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005937 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
5938 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005939 status = PowerUpDevice(state);
5940 if (status < 0)
5941 break;
5942 status = DRXX_Open(state);
5943 if (status < 0)
5944 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005945 /* Soft reset of OFDM-, sys- and osc-clockdomain */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005946 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 -03005947 if (status < 0)
5948 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005949 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005950 if (status < 0)
5951 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005952 /* TODO is this needed, if yes how much delay in worst case scenario */
5953 msleep(1);
5954 state->m_DRXK_A3_PATCH_CODE = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005955 status = GetDeviceCapabilities(state);
5956 if (status < 0)
5957 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005958
5959 /* Bridge delay, uses oscilator clock */
5960 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5961 /* SDA brdige delay */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005962 state->m_HICfgBridgeDelay =
5963 (u16) ((state->m_oscClockFreq / 1000) *
5964 HI_I2C_BRIDGE_DELAY) / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005965 /* Clipping */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005966 if (state->m_HICfgBridgeDelay >
5967 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
5968 state->m_HICfgBridgeDelay =
5969 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005970 }
5971 /* SCL bridge delay, same as SDA for now */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005972 state->m_HICfgBridgeDelay +=
5973 state->m_HICfgBridgeDelay <<
5974 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005975
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005976 status = InitHI(state);
5977 if (status < 0)
5978 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005979 /* disable various processes */
5980#if NOA1ROM
Oliver Endrissebc7de22011-07-03 13:49:44 -03005981 if (!(state->m_DRXK_A1_ROM_CODE)
5982 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005983#endif
5984 {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005985 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005986 if (status < 0)
5987 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005988 }
5989
5990 /* disable MPEG port */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005991 status = MPEGTSDisable(state);
5992 if (status < 0)
5993 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005994
5995 /* Stop AUD and SCU */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005996 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005997 if (status < 0)
5998 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005999 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006000 if (status < 0)
6001 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006002
6003 /* enable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006004 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 -03006005 if (status < 0)
6006 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006007
6008 /* include boot loader section */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006009 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006010 if (status < 0)
6011 break;
6012 status = BLChainCmd(state, 0, 6, 100);
6013 if (status < 0)
6014 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006015
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006016 if (!state->microcode_name)
6017 load_microcode(state, "drxk_a3.mc");
6018 else
6019 load_microcode(state, state->microcode_name);
6020
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006021 /* disable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006022 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 -03006023 if (status < 0)
6024 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006025
6026 /* Run SCU for a little while to initialize microcode version numbers */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006027 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006028 if (status < 0)
6029 break;
6030 status = DRXX_Open(state);
6031 if (status < 0)
6032 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006033 /* added for test */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006034 msleep(30);
6035
6036 powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006037 status = CtrlPowerMode(state, &powerMode);
6038 if (status < 0)
6039 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006040
6041 /* Stamp driver version number in SCU data RAM in BCD code
6042 Done to enable field application engineers to retreive drxdriver version
6043 via I2C from SCU RAM.
6044 Not using SCU command interface for SCU register access since no
6045 microcode may be present.
Oliver Endrissebc7de22011-07-03 13:49:44 -03006046 */
6047 driverVersion =
6048 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6049 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6050 ((DRXK_VERSION_MAJOR % 10) << 4) +
6051 (DRXK_VERSION_MINOR % 10);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006052 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006053 if (status < 0)
6054 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006055 driverVersion =
6056 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6057 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6058 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6059 (DRXK_VERSION_PATCH % 10);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006060 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006061 if (status < 0)
6062 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006063
Oliver Endrissebc7de22011-07-03 13:49:44 -03006064 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6065 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6066 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006067
6068 /* Dirty fix of default values for ROM/PATCH microcode
6069 Dirty because this fix makes it impossible to setup suitable values
6070 before calling DRX_Open. This solution requires changes to RF AGC speed
6071 to be done via the CTRL function after calling DRX_Open */
6072
Oliver Endrissebc7de22011-07-03 13:49:44 -03006073 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006074
6075 /* Reset driver debug flags to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006076 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006077 if (status < 0)
6078 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006079 /* driver 0.9.0 */
6080 /* Setup FEC OC:
6081 NOTE: No more full FEC resets allowed afterwards!! */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006082 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006083 if (status < 0)
6084 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006085 /* MPEGTS functions are still the same */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006086 status = MPEGTSDtoInit(state);
6087 if (status < 0)
6088 break;
6089 status = MPEGTSStop(state);
6090 if (status < 0)
6091 break;
6092 status = MPEGTSConfigurePolarity(state);
6093 if (status < 0)
6094 break;
6095 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6096 if (status < 0)
6097 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006098 /* added: configure GPIO */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006099 status = WriteGPIO(state);
6100 if (status < 0)
6101 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006102
Oliver Endrissebc7de22011-07-03 13:49:44 -03006103 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006104
6105 if (state->m_bPowerDown) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006106 status = PowerDownDevice(state);
6107 if (status < 0)
6108 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006109 state->m_DrxkState = DRXK_POWERED_DOWN;
6110 } else
6111 state->m_DrxkState = DRXK_STOPPED;
6112 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006113 }
6114
6115 return 0;
6116}
6117
Oliver Endrissebc7de22011-07-03 13:49:44 -03006118static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006119{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006120 struct drxk_state *state = fe->demodulator_priv;
6121
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006122 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006123 kfree(state);
6124}
6125
Oliver Endrissebc7de22011-07-03 13:49:44 -03006126static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006127{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006128 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006129
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006130 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006131 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006132 return -EBUSY;
6133 SetOperationMode(state, OM_QAM_ITU_A);
6134 return 0;
6135}
6136
Oliver Endrissebc7de22011-07-03 13:49:44 -03006137static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006138{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006139 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006140
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006141 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006142 ShutDown(state);
6143 mutex_unlock(&state->ctlock);
6144 return 0;
6145}
6146
Oliver Endrissebc7de22011-07-03 13:49:44 -03006147static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006148{
6149 struct drxk_state *state = fe->demodulator_priv;
6150
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006151 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006152 return ConfigureI2CBridge(state, enable ? true : false);
6153}
6154
Oliver Endrissebc7de22011-07-03 13:49:44 -03006155static int drxk_set_parameters(struct dvb_frontend *fe,
6156 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006157{
6158 struct drxk_state *state = fe->demodulator_priv;
6159 u32 IF;
6160
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006161 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006162 if (fe->ops.i2c_gate_ctrl)
6163 fe->ops.i2c_gate_ctrl(fe, 1);
6164 if (fe->ops.tuner_ops.set_params)
6165 fe->ops.tuner_ops.set_params(fe, p);
6166 if (fe->ops.i2c_gate_ctrl)
6167 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006168 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006169 fe->ops.tuner_ops.get_frequency(fe, &IF);
6170 Start(state, 0, IF);
6171
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006172 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006173
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006174 return 0;
6175}
6176
Oliver Endrissebc7de22011-07-03 13:49:44 -03006177static int drxk_c_get_frontend(struct dvb_frontend *fe,
6178 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006179{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006180 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006181 return 0;
6182}
6183
6184static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6185{
6186 struct drxk_state *state = fe->demodulator_priv;
6187 u32 stat;
6188
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006189 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006190 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006191 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006192 if (stat == MPEG_LOCK)
6193 *status |= 0x1f;
6194 if (stat == FEC_LOCK)
6195 *status |= 0x0f;
6196 if (stat == DEMOD_LOCK)
6197 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006198 return 0;
6199}
6200
6201static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6202{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006203 dprintk(1, "\n");
6204
Oliver Endrissebc7de22011-07-03 13:49:44 -03006205 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006206 return 0;
6207}
6208
Oliver Endrissebc7de22011-07-03 13:49:44 -03006209static int drxk_read_signal_strength(struct dvb_frontend *fe,
6210 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006211{
6212 struct drxk_state *state = fe->demodulator_priv;
6213 u32 val;
6214
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006215 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006216 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006217 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006218 return 0;
6219}
6220
6221static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6222{
6223 struct drxk_state *state = fe->demodulator_priv;
6224 s32 snr2;
6225
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006226 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006227 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006228 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006229 return 0;
6230}
6231
6232static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6233{
6234 struct drxk_state *state = fe->demodulator_priv;
6235 u16 err;
6236
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006237 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006238 DVBTQAMGetAccPktErr(state, &err);
6239 *ucblocks = (u32) err;
6240 return 0;
6241}
6242
Oliver Endrissebc7de22011-07-03 13:49:44 -03006243static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6244 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006245{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006246 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006247 sets->min_delay_ms = 3000;
6248 sets->max_drift = 0;
6249 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006250 return 0;
6251}
6252
Oliver Endrissebc7de22011-07-03 13:49:44 -03006253static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006254{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006255#if 0
6256 struct drxk_state *state = fe->demodulator_priv;
6257
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006258 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006259 kfree(state);
6260#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006261}
6262
Oliver Endrissebc7de22011-07-03 13:49:44 -03006263static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006264{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006265 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006266
6267 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006268 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006269 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006270 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006271 return 0;
6272}
6273
Oliver Endrissebc7de22011-07-03 13:49:44 -03006274static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006275{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006276 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006277
6278 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006279 mutex_unlock(&state->ctlock);
6280 return 0;
6281}
6282
Oliver Endrissebc7de22011-07-03 13:49:44 -03006283static int drxk_t_get_frontend(struct dvb_frontend *fe,
6284 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006285{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006286 dprintk(1, "\n");
6287
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006288 return 0;
6289}
6290
6291static struct dvb_frontend_ops drxk_c_ops = {
6292 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006293 .name = "DRXK DVB-C",
6294 .type = FE_QAM,
6295 .frequency_stepsize = 62500,
6296 .frequency_min = 47000000,
6297 .frequency_max = 862000000,
6298 .symbol_rate_min = 870000,
6299 .symbol_rate_max = 11700000,
6300 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6301 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006302 .release = drxk_c_release,
6303 .init = drxk_c_init,
6304 .sleep = drxk_c_sleep,
6305 .i2c_gate_ctrl = drxk_gate_ctrl,
6306
6307 .set_frontend = drxk_set_parameters,
6308 .get_frontend = drxk_c_get_frontend,
6309 .get_tune_settings = drxk_c_get_tune_settings,
6310
6311 .read_status = drxk_read_status,
6312 .read_ber = drxk_read_ber,
6313 .read_signal_strength = drxk_read_signal_strength,
6314 .read_snr = drxk_read_snr,
6315 .read_ucblocks = drxk_read_ucblocks,
6316};
6317
6318static struct dvb_frontend_ops drxk_t_ops = {
6319 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006320 .name = "DRXK DVB-T",
6321 .type = FE_OFDM,
6322 .frequency_min = 47125000,
6323 .frequency_max = 865000000,
6324 .frequency_stepsize = 166667,
6325 .frequency_tolerance = 0,
6326 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6327 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6328 FE_CAN_FEC_AUTO |
6329 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6330 FE_CAN_QAM_AUTO |
6331 FE_CAN_TRANSMISSION_MODE_AUTO |
6332 FE_CAN_GUARD_INTERVAL_AUTO |
6333 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006334 .release = drxk_t_release,
6335 .init = drxk_t_init,
6336 .sleep = drxk_t_sleep,
6337 .i2c_gate_ctrl = drxk_gate_ctrl,
6338
6339 .set_frontend = drxk_set_parameters,
6340 .get_frontend = drxk_t_get_frontend,
6341
6342 .read_status = drxk_read_status,
6343 .read_ber = drxk_read_ber,
6344 .read_signal_strength = drxk_read_signal_strength,
6345 .read_snr = drxk_read_snr,
6346 .read_ucblocks = drxk_read_ucblocks,
6347};
6348
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006349struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6350 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006351 struct dvb_frontend **fe_t)
6352{
6353 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006354 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006355
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006356 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006357 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006358 if (!state)
6359 return NULL;
6360
Oliver Endrissebc7de22011-07-03 13:49:44 -03006361 state->i2c = i2c;
6362 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006363 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006364 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006365 state->no_i2c_bridge = config->no_i2c_bridge;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006366
6367 mutex_init(&state->mutex);
6368 mutex_init(&state->ctlock);
6369
Oliver Endrissebc7de22011-07-03 13:49:44 -03006370 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6371 sizeof(struct dvb_frontend_ops));
6372 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6373 sizeof(struct dvb_frontend_ops));
6374 state->c_frontend.demodulator_priv = state;
6375 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006376
6377 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006378 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006379 goto error;
6380 *fe_t = &state->t_frontend;
6381 return &state->c_frontend;
6382
6383error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006384 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006385 kfree(state);
6386 return NULL;
6387}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006388EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006389
6390MODULE_DESCRIPTION("DRX-K driver");
6391MODULE_AUTHOR("Ralph Metzler");
6392MODULE_LICENSE("GPL");