blob: 89db378358728c0763810e4290b5fed365c46ea4 [file] [log] [blame]
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001/*
2 * drxk_hard: DRX-K DVB-C/T demodulator driver
3 *
4 * Copyright (C) 2010-2011 Digital Devices GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/firmware.h>
30#include <linux/i2c.h>
31#include <linux/version.h>
32#include <asm/div64.h>
33
34#include "dvb_frontend.h"
35#include "drxk.h"
36#include "drxk_hard.h"
37
38static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
39static int PowerDownQAM(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030040static int SetDVBTStandard(struct drxk_state *state,
41 enum OperationMode oMode);
42static int SetQAMStandard(struct drxk_state *state,
43 enum OperationMode oMode);
44static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
Ralph Metzler43dd07f2011-07-03 13:42:18 -030045 s32 tunerFreqOffset);
Oliver Endrissebc7de22011-07-03 13:49:44 -030046static int SetDVBTStandard(struct drxk_state *state,
47 enum OperationMode oMode);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030048static int DVBTStart(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030049static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
50 s32 tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030051static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
52static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
53static int SwitchAntennaToQAM(struct drxk_state *state);
54static int SwitchAntennaToDVBT(struct drxk_state *state);
55
56static bool IsDVBT(struct drxk_state *state)
57{
58 return state->m_OperationMode == OM_DVBT;
59}
60
61static bool IsQAM(struct drxk_state *state)
62{
63 return state->m_OperationMode == OM_QAM_ITU_A ||
Oliver Endrissebc7de22011-07-03 13:49:44 -030064 state->m_OperationMode == OM_QAM_ITU_B ||
65 state->m_OperationMode == OM_QAM_ITU_C;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030066}
67
68bool IsA1WithPatchCode(struct drxk_state *state)
69{
70 return state->m_DRXK_A1_PATCH_CODE;
71}
72
73bool IsA1WithRomCode(struct drxk_state *state)
74{
75 return state->m_DRXK_A1_ROM_CODE;
76}
77
78#define NOA1ROM 0
79
Ralph Metzler43dd07f2011-07-03 13:42:18 -030080#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
81#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
82
83#define DEFAULT_MER_83 165
84#define DEFAULT_MER_93 250
85
86#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
87#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
88#endif
89
90#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
91#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
92#endif
93
94#ifndef DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH
95#define DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH (0x06)
96#endif
97
98#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
99#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
100
101#ifndef DRXK_KI_RAGC_ATV
102#define DRXK_KI_RAGC_ATV 4
103#endif
104#ifndef DRXK_KI_IAGC_ATV
105#define DRXK_KI_IAGC_ATV 6
106#endif
107#ifndef DRXK_KI_DAGC_ATV
108#define DRXK_KI_DAGC_ATV 7
109#endif
110
111#ifndef DRXK_KI_RAGC_QAM
112#define DRXK_KI_RAGC_QAM 3
113#endif
114#ifndef DRXK_KI_IAGC_QAM
115#define DRXK_KI_IAGC_QAM 4
116#endif
117#ifndef DRXK_KI_DAGC_QAM
118#define DRXK_KI_DAGC_QAM 7
119#endif
120#ifndef DRXK_KI_RAGC_DVBT
121#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
122#endif
123#ifndef DRXK_KI_IAGC_DVBT
124#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
125#endif
126#ifndef DRXK_KI_DAGC_DVBT
127#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
128#endif
129
130#ifndef DRXK_AGC_DAC_OFFSET
131#define DRXK_AGC_DAC_OFFSET (0x800)
132#endif
133
134#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
135#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
136#endif
137
138#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
139#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
140#endif
141
142#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
143#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
144#endif
145
146#ifndef DRXK_QAM_SYMBOLRATE_MAX
147#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
148#endif
149
150#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
151#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
152#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
153#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
154#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
155#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
156#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
157#define DRXK_BL_ROM_OFFSET_UCODE 0
158
159#define DRXK_BLC_TIMEOUT 100
160
161#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
162#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
163
164#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
165
166#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
167#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
168#endif
169
170#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
171#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
172#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
173#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
174#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
175
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300176static unsigned int debug;
177module_param(debug, int, 0644);
178MODULE_PARM_DESC(debug, "enable debug messages");
179
180#define dprintk(level, fmt, arg...) do { \
181if (debug >= level) \
182 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
183} while (0)
184
185
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300186static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300187{
188 u64 tmp64;
189
Oliver Endrissebc7de22011-07-03 13:49:44 -0300190 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300191 do_div(tmp64, c);
192
193 return (u32) tmp64;
194}
195
196inline u32 Frac28a(u32 a, u32 c)
197{
198 int i = 0;
199 u32 Q1 = 0;
200 u32 R0 = 0;
201
Oliver Endrissebc7de22011-07-03 13:49:44 -0300202 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
203 Q1 = a / c; /* integer part, only the 4 least significant bits
204 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300205
206 /* division using radix 16, 7 nibbles in the result */
207 for (i = 0; i < 7; i++) {
208 Q1 = (Q1 << 4) | (R0 / c);
209 R0 = (R0 % c) << 4;
210 }
211 /* rounding */
212 if ((R0 >> 3) >= c)
213 Q1++;
214
215 return Q1;
216}
217
218static u32 Log10Times100(u32 x)
219{
220 static const u8 scale = 15;
221 static const u8 indexWidth = 5;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300222 u8 i = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300223 u32 y = 0;
224 u32 d = 0;
225 u32 k = 0;
226 u32 r = 0;
227 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300228 log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
229 0 <= n < ((1<<INDEXWIDTH)+1)
230 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300231
232 static const u32 log2lut[] = {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300233 0, /* 0.000000 */
234 290941, /* 290941.300628 */
235 573196, /* 573196.476418 */
236 847269, /* 847269.179851 */
237 1113620, /* 1113620.489452 */
238 1372674, /* 1372673.576986 */
239 1624818, /* 1624817.752104 */
240 1870412, /* 1870411.981536 */
241 2109788, /* 2109787.962654 */
242 2343253, /* 2343252.817465 */
243 2571091, /* 2571091.461923 */
244 2793569, /* 2793568.696416 */
245 3010931, /* 3010931.055901 */
246 3223408, /* 3223408.452106 */
247 3431216, /* 3431215.635215 */
248 3634553, /* 3634553.498355 */
249 3833610, /* 3833610.244726 */
250 4028562, /* 4028562.434393 */
251 4219576, /* 4219575.925308 */
252 4406807, /* 4406806.721144 */
253 4590402, /* 4590401.736809 */
254 4770499, /* 4770499.491025 */
255 4947231, /* 4947230.734179 */
256 5120719, /* 5120719.018555 */
257 5291081, /* 5291081.217197 */
258 5458428, /* 5458427.996830 */
259 5622864, /* 5622864.249668 */
260 5784489, /* 5784489.488298 */
261 5943398, /* 5943398.207380 */
262 6099680, /* 6099680.215452 */
263 6253421, /* 6253420.939751 */
264 6404702, /* 6404701.706649 */
265 6553600, /* 6553600.000000 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300266 };
267
268
269 if (x == 0)
Oliver Endrissebc7de22011-07-03 13:49:44 -0300270 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300271
272 /* Scale x (normalize) */
273 /* computing y in log(x/y) = log(x) - log(y) */
274 if ((x & ((0xffffffff) << (scale + 1))) == 0) {
275 for (k = scale; k > 0; k--) {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300276 if (x & (((u32) 1) << scale))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300277 break;
278 x <<= 1;
279 }
280 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300281 for (k = scale; k < 31; k++) {
282 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300283 break;
284 x >>= 1;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300285 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300286 }
287 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300288 Now x has binary point between bit[scale] and bit[scale-1]
289 and 1.0 <= x < 2.0 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300290
291 /* correction for divison: log(x) = log(x/y)+log(y) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300292 y = k * ((((u32) 1) << scale) * 200);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300293
294 /* remove integer part */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300295 x &= ((((u32) 1) << scale) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300296 /* get index */
297 i = (u8) (x >> (scale - indexWidth));
298 /* compute delta (x - a) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300299 d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300300 /* compute log, multiplication (d* (..)) must be within range ! */
301 y += log2lut[i] +
Oliver Endrissebc7de22011-07-03 13:49:44 -0300302 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300303 /* Conver to log10() */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300304 y /= 108853; /* (log2(10) << scale) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300305 r = (y >> 1);
306 /* rounding */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300307 if (y & ((u32) 1))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300308 r++;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300309 return r;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300310}
311
312/****************************************************************************/
313/* I2C **********************************************************************/
314/****************************************************************************/
315
316static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val)
317{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300318 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
319 .buf = val, .len = 1}
320 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300321 return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
322}
323
324static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
325{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300326 struct i2c_msg msg = {
327 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300328
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300329 dprintk(3, ":");
330 if (debug > 2) {
331 int i;
332 for (i = 0; i < len; i++)
333 printk(KERN_CONT " %02x", data[i]);
334 printk(KERN_CONT "\n");
335 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300336 if (i2c_transfer(adap, &msg, 1) != 1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300337 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300338 return -1;
339 }
340 return 0;
341}
342
343static int i2c_read(struct i2c_adapter *adap,
344 u8 adr, u8 *msg, int len, u8 *answ, int alen)
345{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300346 struct i2c_msg msgs[2] = { {.addr = adr, .flags = 0,
347 .buf = msg, .len = len},
348 {.addr = adr, .flags = I2C_M_RD,
349 .buf = answ, .len = alen}
350 };
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300351 dprintk(3, ":");
352 if (debug > 2) {
353 int i;
354 for (i = 0; i < len; i++)
355 printk(KERN_CONT " %02x", msg[i]);
356 printk(KERN_CONT "\n");
357 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300358 if (i2c_transfer(adap, msgs, 2) != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300359 if (debug > 2)
360 printk(KERN_CONT ": ERROR!\n");
361
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300362 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300363 return -1;
364 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300365 if (debug > 2) {
366 int i;
367 printk(KERN_CONT ": Read ");
368 for (i = 0; i < len; i++)
369 printk(KERN_CONT " %02x", msg[i]);
370 printk(KERN_CONT "\n");
371 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300372 return 0;
373}
374
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300375static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300376{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300377 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300378
379 if (state->single_master)
380 flags |= 0xC0;
381
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300382 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
383 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
384 mm1[1] = ((reg >> 16) & 0xFF);
385 mm1[2] = ((reg >> 24) & 0xFF) | flags;
386 mm1[3] = ((reg >> 7) & 0xFF);
387 len = 4;
388 } else {
389 mm1[0] = ((reg << 1) & 0xFF);
390 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
391 len = 2;
392 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300393 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300394 if (i2c_read(state->i2c, adr, mm1, len, mm2, 2) < 0)
395 return -1;
396 if (data)
397 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300398
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300399 return 0;
400}
401
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300402static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300403{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300404 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300405}
406
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300407static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300408{
409 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300410
411 if (state->single_master)
412 flags |= 0xC0;
413
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300414 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
415 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
416 mm1[1] = ((reg >> 16) & 0xFF);
417 mm1[2] = ((reg >> 24) & 0xFF) | flags;
418 mm1[3] = ((reg >> 7) & 0xFF);
419 len = 4;
420 } else {
421 mm1[0] = ((reg << 1) & 0xFF);
422 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
423 len = 2;
424 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300425 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300426 if (i2c_read(state->i2c, adr, mm1, len, mm2, 4) < 0)
427 return -1;
428 if (data)
429 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300430 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300431
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300432 return 0;
433}
434
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300435static int read32(struct drxk_state *state, u32 reg, u32 *data)
436{
437 return read32_flags(state, reg, data, 0);
438}
439
440static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300441{
442 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300443
444 if (state->single_master)
445 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300446 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
447 mm[0] = (((reg << 1) & 0xFF) | 0x01);
448 mm[1] = ((reg >> 16) & 0xFF);
449 mm[2] = ((reg >> 24) & 0xFF) | flags;
450 mm[3] = ((reg >> 7) & 0xFF);
451 len = 4;
452 } else {
453 mm[0] = ((reg << 1) & 0xFF);
454 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
455 len = 2;
456 }
457 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300458 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300459
460 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300461 if (i2c_write(state->i2c, adr, mm, len + 2) < 0)
462 return -1;
463 return 0;
464}
465
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300466static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300467{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300468 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300469}
470
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300471static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300472{
473 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300474
475 if (state->single_master)
476 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300477 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
478 mm[0] = (((reg << 1) & 0xFF) | 0x01);
479 mm[1] = ((reg >> 16) & 0xFF);
480 mm[2] = ((reg >> 24) & 0xFF) | flags;
481 mm[3] = ((reg >> 7) & 0xFF);
482 len = 4;
483 } else {
484 mm[0] = ((reg << 1) & 0xFF);
485 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
486 len = 2;
487 }
488 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300489 mm[len + 1] = (data >> 8) & 0xff;
490 mm[len + 2] = (data >> 16) & 0xff;
491 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300492 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300493 if (i2c_write(state->i2c, adr, mm, len + 4) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300494 return -1;
495 return 0;
496}
497
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300498static int write32(struct drxk_state *state, u32 reg, u32 data)
499{
500 return write32_flags(state, reg, data, 0);
501}
502
503static int write_block(struct drxk_state *state, u32 Address,
504 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300505{
506 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300507 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300508
509 if (state->single_master)
510 Flags |= 0xC0;
511
Oliver Endrissebc7de22011-07-03 13:49:44 -0300512 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300513 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300514 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300515 u8 *AdrBuf = &state->Chunk[0];
516 u32 AdrLength = 0;
517
Oliver Endrissebc7de22011-07-03 13:49:44 -0300518 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
519 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
520 AdrBuf[1] = ((Address >> 16) & 0xFF);
521 AdrBuf[2] = ((Address >> 24) & 0xFF);
522 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300523 AdrBuf[2] |= Flags;
524 AdrLength = 4;
525 if (Chunk == state->m_ChunkSize)
526 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300527 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300528 AdrBuf[0] = ((Address << 1) & 0xFF);
529 AdrBuf[1] = (((Address >> 16) & 0x0F) |
530 ((Address >> 18) & 0xF0));
531 AdrLength = 2;
532 }
533 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300534 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
535 if (debug > 1) {
536 int i;
537 if (pBlock)
538 for (i = 0; i < Chunk; i++)
539 printk(KERN_CONT " %02x", pBlock[i]);
540 printk(KERN_CONT "\n");
541 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300542 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300543 &state->Chunk[0], Chunk + AdrLength);
544 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300545 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
546 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300547 break;
548 }
549 pBlock += Chunk;
550 Address += (Chunk >> 1);
551 BlkSize -= Chunk;
552 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300553 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300554}
555
556#ifndef DRXK_MAX_RETRIES_POWERUP
557#define DRXK_MAX_RETRIES_POWERUP 20
558#endif
559
560int PowerUpDevice(struct drxk_state *state)
561{
562 int status;
563 u8 data = 0;
564 u16 retryCount = 0;
565
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300566 dprintk(1, "\n");
567
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300568 status = i2c_read1(state->i2c, state->demod_address, &data);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300569 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300570 do {
571 data = 0;
572 if (i2c_write(state->i2c,
573 state->demod_address, &data, 1) < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300574 printk(KERN_ERR "drxk: powerup failed\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300575 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300576 retryCount++;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300577 } while (i2c_read1(state->i2c,
578 state->demod_address, &data) < 0 &&
579 (retryCount < DRXK_MAX_RETRIES_POWERUP));
580 if (retryCount >= DRXK_MAX_RETRIES_POWERUP)
581 return -1;
582 do {
583 /* Make sure all clk domains are active */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300584 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300585 if (status < 0)
586 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300587 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300588 if (status < 0)
589 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300590 /* Enable pll lock tests */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300591 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300592 if (status < 0)
593 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300594 state->m_currentPowerMode = DRX_POWER_UP;
595 } while (0);
596 return status;
597}
598
599
600static int init_state(struct drxk_state *state)
601{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300602 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
603 u32 ulVSBIfAgcOutputLevel = 0;
604 u32 ulVSBIfAgcMinLevel = 0;
605 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
606 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300607
Oliver Endrissebc7de22011-07-03 13:49:44 -0300608 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
609 u32 ulVSBRfAgcOutputLevel = 0;
610 u32 ulVSBRfAgcMinLevel = 0;
611 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
612 u32 ulVSBRfAgcSpeed = 3;
613 u32 ulVSBRfAgcTop = 9500;
614 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300615
Oliver Endrissebc7de22011-07-03 13:49:44 -0300616 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
617 u32 ulATVIfAgcOutputLevel = 0;
618 u32 ulATVIfAgcMinLevel = 0;
619 u32 ulATVIfAgcMaxLevel = 0;
620 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300621
Oliver Endrissebc7de22011-07-03 13:49:44 -0300622 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
623 u32 ulATVRfAgcOutputLevel = 0;
624 u32 ulATVRfAgcMinLevel = 0;
625 u32 ulATVRfAgcMaxLevel = 0;
626 u32 ulATVRfAgcTop = 9500;
627 u32 ulATVRfAgcCutOffCurrent = 4000;
628 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300629
630 u32 ulQual83 = DEFAULT_MER_83;
631 u32 ulQual93 = DEFAULT_MER_93;
632
633 u32 ulDVBTStaticTSClock = 1;
634 u32 ulDVBCStaticTSClock = 1;
635
636 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
637 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
638
639 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
640 /* io_pad_cfg_mode output mode is drive always */
641 /* io_pad_cfg_drive is set to power 2 (23 mA) */
642 u32 ulGPIOCfg = 0x0113;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300643 u32 ulGPIO = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300644 u32 ulSerialMode = 1;
645 u32 ulInvertTSClock = 0;
646 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
647 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
648 u32 ulDVBTBitrate = 50000000;
649 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
650
651 u32 ulInsertRSByte = 0;
652
653 u32 ulRfMirror = 1;
654 u32 ulPowerDown = 0;
655
656 u32 ulAntennaDVBT = 1;
657 u32 ulAntennaDVBC = 0;
658 u32 ulAntennaSwitchDVBTDVBC = 0;
659
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300660 dprintk(1, "\n");
661
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300662 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300663 state->m_hasDVBT = false;
664 state->m_hasDVBC = false;
665 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300666 state->m_hasOOB = false;
667 state->m_hasAudio = false;
668
669 state->m_ChunkSize = 124;
670
671 state->m_oscClockFreq = 0;
672 state->m_smartAntInverted = false;
673 state->m_bPDownOpenBridge = false;
674
675 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300676 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300677 /* Timing div, 250ns/Psys */
678 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
679 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
680 HI_I2C_DELAY) / 1000;
681 /* Clipping */
682 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
683 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
684 state->m_HICfgWakeUpKey = (state->demod_address << 1);
685 /* port/bridge/power down ctrl */
686 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
687
688 state->m_bPowerDown = (ulPowerDown != 0);
689
690 state->m_DRXK_A1_PATCH_CODE = false;
691 state->m_DRXK_A1_ROM_CODE = false;
692 state->m_DRXK_A2_ROM_CODE = false;
693 state->m_DRXK_A3_ROM_CODE = false;
694 state->m_DRXK_A2_PATCH_CODE = false;
695 state->m_DRXK_A3_PATCH_CODE = false;
696
697 /* Init AGC and PGA parameters */
698 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300699 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
700 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
701 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
702 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
703 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300704 state->m_vsbPgaCfg = 140;
705
706 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300707 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
708 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
709 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
710 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
711 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
712 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
713 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
714 state->m_vsbPreSawCfg.reference = 0x07;
715 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300716
717 state->m_Quality83percent = DEFAULT_MER_83;
718 state->m_Quality93percent = DEFAULT_MER_93;
719 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
720 state->m_Quality83percent = ulQual83;
721 state->m_Quality93percent = ulQual93;
722 }
723
724 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300725 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
726 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
727 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
728 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
729 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300730
731 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300732 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
733 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
734 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
735 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
736 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
737 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
738 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
739 state->m_atvPreSawCfg.reference = 0x04;
740 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300741
742
743 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300744 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
745 state->m_dvbtRfAgcCfg.outputLevel = 0;
746 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
747 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
748 state->m_dvbtRfAgcCfg.top = 0x2100;
749 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
750 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300751
752
753 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300754 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
755 state->m_dvbtIfAgcCfg.outputLevel = 0;
756 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
757 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
758 state->m_dvbtIfAgcCfg.top = 13424;
759 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
760 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300761 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300762 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
763 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300764
Oliver Endrissebc7de22011-07-03 13:49:44 -0300765 state->m_dvbtPreSawCfg.reference = 4;
766 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300767
768 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300769 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
770 state->m_qamRfAgcCfg.outputLevel = 0;
771 state->m_qamRfAgcCfg.minOutputLevel = 6023;
772 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
773 state->m_qamRfAgcCfg.top = 0x2380;
774 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
775 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300776
777 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300778 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
779 state->m_qamIfAgcCfg.outputLevel = 0;
780 state->m_qamIfAgcCfg.minOutputLevel = 0;
781 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
782 state->m_qamIfAgcCfg.top = 0x0511;
783 state->m_qamIfAgcCfg.cutOffCurrent = 0;
784 state->m_qamIfAgcCfg.speed = 3;
785 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300786 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
787
Oliver Endrissebc7de22011-07-03 13:49:44 -0300788 state->m_qamPgaCfg = 140;
789 state->m_qamPreSawCfg.reference = 4;
790 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300791
792 state->m_OperationMode = OM_NONE;
793 state->m_DrxkState = DRXK_UNINITIALIZED;
794
795 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300796 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
797 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
798 state->m_enableParallel = true; /* If TRUE;
799 parallel out otherwise serial */
800 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
801 state->m_invertERR = false; /* If TRUE; invert ERR signal */
802 state->m_invertSTR = false; /* If TRUE; invert STR signals */
803 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
804 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300805 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300806 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300807 /* If TRUE; static MPEG clockrate will be used;
808 otherwise clockrate will adapt to the bitrate of the TS */
809
810 state->m_DVBTBitrate = ulDVBTBitrate;
811 state->m_DVBCBitrate = ulDVBCBitrate;
812
813 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
814 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
815
816 /* Maximum bitrate in b/s in case static clockrate is selected */
817 state->m_mpegTsStaticBitrate = 19392658;
818 state->m_disableTEIhandling = false;
819
820 if (ulInsertRSByte)
821 state->m_insertRSByte = true;
822
823 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
824 if (ulMpegLockTimeOut < 10000)
825 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
826 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
827 if (ulDemodLockTimeOut < 10000)
828 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
829
Oliver Endrissebc7de22011-07-03 13:49:44 -0300830 /* QAM defaults */
831 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300832 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300833 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
834 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300835
836 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
837 state->m_agcFastClipCtrlDelay = 0;
838
839 state->m_GPIOCfg = (ulGPIOCfg);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300840 state->m_GPIO = (ulGPIO == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300841
842 state->m_AntennaDVBT = (ulAntennaDVBT == 0 ? 0 : 1);
843 state->m_AntennaDVBC = (ulAntennaDVBC == 0 ? 0 : 1);
844 state->m_AntennaSwitchDVBTDVBC =
Oliver Endrissebc7de22011-07-03 13:49:44 -0300845 (ulAntennaSwitchDVBTDVBC == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300846
847 state->m_bPowerDown = false;
848 state->m_currentPowerMode = DRX_POWER_DOWN;
849
850 state->m_enableParallel = (ulSerialMode == 0);
851
852 state->m_rfmirror = (ulRfMirror == 0);
853 state->m_IfAgcPol = false;
854 return 0;
855}
856
857static int DRXX_Open(struct drxk_state *state)
858{
859 int status = 0;
860 u32 jtag = 0;
861 u16 bid = 0;
862 u16 key = 0;
863
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300864 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300865 do {
866 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300867 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300868 if (status < 0)
869 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300870 /* Check device id */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300871 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300872 if (status < 0)
873 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300874 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300875 if (status < 0)
876 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300877 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300878 if (status < 0)
879 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300880 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300881 if (status < 0)
882 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300883 status = write16(state, SIO_TOP_COMM_KEY__A, key);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300884 if (status < 0)
885 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300886 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300887 return status;
888}
889
890static int GetDeviceCapabilities(struct drxk_state *state)
891{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300892 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300893 u32 sioTopJtagidLo = 0;
894 int status;
895
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300896 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300897 do {
898 /* driver 0.9.0 */
899 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300900 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300901 if (status < 0)
902 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300903
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300904 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300905 if (status < 0)
906 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300907 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300908 if (status < 0)
909 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300910 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300911 if (status < 0)
912 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300913
914 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
915 case 0:
916 /* ignore (bypass ?) */
917 break;
918 case 1:
919 /* 27 MHz */
920 state->m_oscClockFreq = 27000;
921 break;
922 case 2:
923 /* 20.25 MHz */
924 state->m_oscClockFreq = 20250;
925 break;
926 case 3:
927 /* 4 MHz */
928 state->m_oscClockFreq = 20250;
929 break;
930 default:
931 return -1;
932 }
933 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300934 Determine device capabilities
935 Based on pinning v14
936 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300937 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300938 if (status < 0)
939 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300940 /* driver 0.9.0 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300941 switch ((sioTopJtagidLo >> 29) & 0xF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300942 case 0:
943 state->m_deviceSpin = DRXK_SPIN_A1;
944 break;
945 case 2:
946 state->m_deviceSpin = DRXK_SPIN_A2;
947 break;
948 case 3:
949 state->m_deviceSpin = DRXK_SPIN_A3;
950 break;
951 default:
952 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
953 status = -1;
954 break;
955 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300956 switch ((sioTopJtagidLo >> 12) & 0xFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300957 case 0x13:
958 /* typeId = DRX3913K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300959 state->m_hasLNA = false;
960 state->m_hasOOB = false;
961 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300962 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300963 state->m_hasDVBT = true;
964 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300965 state->m_hasSAWSW = true;
966 state->m_hasGPIO2 = false;
967 state->m_hasGPIO1 = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300968 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300969 break;
970 case 0x15:
971 /* typeId = DRX3915K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300972 state->m_hasLNA = false;
973 state->m_hasOOB = false;
974 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300975 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300976 state->m_hasDVBT = true;
977 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300978 state->m_hasSAWSW = true;
979 state->m_hasGPIO2 = true;
980 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300981 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300982 break;
983 case 0x16:
984 /* typeId = DRX3916K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300985 state->m_hasLNA = false;
986 state->m_hasOOB = false;
987 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300988 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300989 state->m_hasDVBT = true;
990 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300991 state->m_hasSAWSW = true;
992 state->m_hasGPIO2 = true;
993 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300994 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300995 break;
996 case 0x18:
997 /* typeId = DRX3918K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300998 state->m_hasLNA = false;
999 state->m_hasOOB = false;
1000 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001001 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001002 state->m_hasDVBT = true;
1003 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001004 state->m_hasSAWSW = true;
1005 state->m_hasGPIO2 = true;
1006 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001007 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001008 break;
1009 case 0x21:
1010 /* typeId = DRX3921K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001011 state->m_hasLNA = false;
1012 state->m_hasOOB = false;
1013 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001014 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001015 state->m_hasDVBT = true;
1016 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001017 state->m_hasSAWSW = true;
1018 state->m_hasGPIO2 = true;
1019 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001020 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001021 break;
1022 case 0x23:
1023 /* typeId = DRX3923K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001024 state->m_hasLNA = false;
1025 state->m_hasOOB = false;
1026 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001027 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001028 state->m_hasDVBT = true;
1029 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001030 state->m_hasSAWSW = true;
1031 state->m_hasGPIO2 = true;
1032 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001033 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001034 break;
1035 case 0x25:
1036 /* typeId = DRX3925K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001037 state->m_hasLNA = false;
1038 state->m_hasOOB = false;
1039 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001040 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001041 state->m_hasDVBT = true;
1042 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001043 state->m_hasSAWSW = true;
1044 state->m_hasGPIO2 = true;
1045 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001046 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001047 break;
1048 case 0x26:
1049 /* typeId = DRX3926K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001050 state->m_hasLNA = false;
1051 state->m_hasOOB = false;
1052 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001053 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001054 state->m_hasDVBT = true;
1055 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001056 state->m_hasSAWSW = true;
1057 state->m_hasGPIO2 = true;
1058 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001059 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001060 break;
1061 default:
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001062 printk(KERN_ERR "drxk: DeviceID not supported = %02x\n",
Oliver Endrissebc7de22011-07-03 13:49:44 -03001063 ((sioTopJtagidLo >> 12) & 0xFF));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001064 status = -1;
1065 break;
1066 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001067 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001068 return status;
1069}
1070
1071static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1072{
1073 int status;
1074 bool powerdown_cmd;
1075
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001076 dprintk(1, "\n");
1077
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001078 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001079 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001080 if (status < 0)
1081 return status;
1082 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1083 msleep(1);
1084
1085 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001086 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1087 ((state->m_HICfgCtrl) &
1088 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1089 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001090 if (powerdown_cmd == false) {
1091 /* Wait until command rdy */
1092 u32 retryCount = 0;
1093 u16 waitCmd;
1094
1095 do {
1096 msleep(1);
1097 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001098 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1099 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001100 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1101 && (waitCmd != 0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001102
1103 if (status == 0)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001104 status = read16(state, SIO_HI_RA_RAM_RES__A,
1105 pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001106 }
1107 return status;
1108}
1109
1110static int HI_CfgCommand(struct drxk_state *state)
1111{
1112 int status;
1113
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001114 dprintk(1, "\n");
1115
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001116 mutex_lock(&state->mutex);
1117 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001118 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001119 if (status < 0)
1120 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001121 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001122 if (status < 0)
1123 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001124 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001125 if (status < 0)
1126 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001127 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001128 if (status < 0)
1129 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001130 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001131 if (status < 0)
1132 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001133 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001134 if (status < 0)
1135 break;
1136 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1137 if (status < 0)
1138 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001139
1140 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001141 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001142 mutex_unlock(&state->mutex);
1143 return status;
1144}
1145
1146static int InitHI(struct drxk_state *state)
1147{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001148 dprintk(1, "\n");
1149
Oliver Endrissebc7de22011-07-03 13:49:44 -03001150 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001151 state->m_HICfgTimeout = 0x96FF;
1152 /* port/bridge/power down ctrl */
1153 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001154 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001155}
1156
1157static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1158{
1159 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001160 u16 sioPdrMclkCfg = 0;
1161 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001162
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001163 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001164 do {
1165 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001166 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001167 if (status < 0)
1168 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001169
1170 /* MPEG TS pad configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001171 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001172 if (status < 0)
1173 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001174
1175 if (mpegEnable == false) {
1176 /* Set MPEG TS pads to inputmode */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001177 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001178 if (status < 0)
1179 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001180 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001181 if (status < 0)
1182 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001183 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001184 if (status < 0)
1185 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001186 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001187 if (status < 0)
1188 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001189 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001190 if (status < 0)
1191 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001192 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001193 if (status < 0)
1194 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001195 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001196 if (status < 0)
1197 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001198 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001199 if (status < 0)
1200 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001201 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001202 if (status < 0)
1203 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001204 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001205 if (status < 0)
1206 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001207 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001208 if (status < 0)
1209 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001210 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001211 if (status < 0)
1212 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001213 } else {
1214 /* Enable MPEG output */
1215 sioPdrMdxCfg =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001216 ((state->m_TSDataStrength <<
1217 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001218 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03001219 SIO_PDR_MCLK_CFG_DRIVE__B) |
1220 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001221
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001222 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001223 if (status < 0)
1224 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001225 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001226 if (status < 0)
1227 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001228 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001229 if (status < 0)
1230 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001231 if (state->m_enableParallel == true) {
1232 /* paralel -> enable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001233 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001234 if (status < 0)
1235 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001236 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001237 if (status < 0)
1238 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001239 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001240 if (status < 0)
1241 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001242 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001243 if (status < 0)
1244 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001245 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001246 if (status < 0)
1247 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001248 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001249 if (status < 0)
1250 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001251 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001252 if (status < 0)
1253 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001254 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001255 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1256 SIO_PDR_MD0_CFG_DRIVE__B)
1257 | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001258 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001259 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001260 if (status < 0)
1261 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001262 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001263 if (status < 0)
1264 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001265 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001266 if (status < 0)
1267 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001268 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001269 if (status < 0)
1270 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001271 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001272 if (status < 0)
1273 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001274 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001275 if (status < 0)
1276 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001277 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001278 if (status < 0)
1279 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001280 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001281 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001282 if (status < 0)
1283 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001284 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001285 if (status < 0)
1286 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001287 }
1288 /* Enable MB output over MPEG pads and ctl input */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001289 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001290 if (status < 0)
1291 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001292 /* Write nomagic word to enable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001293 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001294 if (status < 0)
1295 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001296 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001297 return status;
1298}
1299
1300static int MPEGTSDisable(struct drxk_state *state)
1301{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001302 dprintk(1, "\n");
1303
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001304 return MPEGTSConfigurePins(state, false);
1305}
1306
1307static int BLChainCmd(struct drxk_state *state,
1308 u16 romOffset, u16 nrOfElements, u32 timeOut)
1309{
1310 u16 blStatus = 0;
1311 int status;
1312 unsigned long end;
1313
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001314 dprintk(1, "\n");
1315
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001316 mutex_lock(&state->mutex);
1317 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001318 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001319 if (status < 0)
1320 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001321 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001322 if (status < 0)
1323 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001324 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001325 if (status < 0)
1326 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001327 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001328 if (status < 0)
1329 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001330 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001331
1332 do {
1333 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001334 status = read16(state, SIO_BL_STATUS__A, &blStatus);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001335 if (status < 0)
1336 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001337 } while ((blStatus == 0x1) &&
1338 ((time_is_after_jiffies(end))));
1339 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001340 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001341 mutex_unlock(&state->mutex);
1342 return -1;
1343 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001344 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001345 mutex_unlock(&state->mutex);
1346 return status;
1347}
1348
1349
1350static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001351 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001352{
1353 const u8 *pSrc = pMCImage;
1354 u16 Flags;
1355 u16 Drain;
1356 u32 Address;
1357 u16 nBlocks;
1358 u16 BlockSize;
1359 u16 BlockCRC;
1360 u32 offset = 0;
1361 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001362 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001363
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001364 dprintk(1, "\n");
1365
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001366 /* down the drain (we don care about MAGIC_WORD) */
1367 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001368 pSrc += sizeof(u16);
1369 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001370 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001371 pSrc += sizeof(u16);
1372 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001373
1374 for (i = 0; i < nBlocks; i += 1) {
1375 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001376 (pSrc[2] << 8) | pSrc[3];
1377 pSrc += sizeof(u32);
1378 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001379
1380 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001381 pSrc += sizeof(u16);
1382 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001383
1384 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001385 pSrc += sizeof(u16);
1386 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001387
1388 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001389 pSrc += sizeof(u16);
1390 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001391
1392 if (offset + BlockSize > Length) {
1393 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1394 return -EINVAL;
1395 }
1396
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001397 status = write_block(state, Address, BlockSize, pSrc);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001398 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001399 break;
1400 pSrc += BlockSize;
1401 offset += BlockSize;
1402 }
1403 return status;
1404}
1405
1406static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1407{
1408 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001409 u16 data = 0;
1410 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001411 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1412 unsigned long end;
1413
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001414 dprintk(1, "\n");
1415
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001416 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001417 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001418 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1419 }
1420
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001421 status = (read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001422
1423 if (data == desiredStatus) {
1424 /* tokenring already has correct status */
1425 return status;
1426 }
1427 /* Disable/enable dvbt tokenring bridge */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001428 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001429 write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001430
Oliver Endrissebc7de22011-07-03 13:49:44 -03001431 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001432 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001433 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001434 if (status < 0)
1435 break;
1436 } while ((data != desiredStatus) && ((time_is_after_jiffies(end))));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001437 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001438 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001439 return -1;
1440 }
1441 return status;
1442}
1443
1444static int MPEGTSStop(struct drxk_state *state)
1445{
1446 int status = 0;
1447 u16 fecOcSncMode = 0;
1448 u16 fecOcIprMode = 0;
1449
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001450 dprintk(1, "\n");
1451
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001452 do {
1453 /* Gracefull shutdown (byte boundaries) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001454 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001455 if (status < 0)
1456 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001457 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001458 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001459 if (status < 0)
1460 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001461
1462 /* Suppress MCLK during absence of data */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001463 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001464 if (status < 0)
1465 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001466 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001467 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001468 if (status < 0)
1469 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001470 } while (0);
1471 return status;
1472}
1473
1474static int scu_command(struct drxk_state *state,
1475 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001476 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001477{
1478#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1479#error DRXK register mapping no longer compatible with this routine!
1480#endif
1481 u16 curCmd = 0;
1482 int status;
1483 unsigned long end;
1484
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001485 dprintk(1, "\n");
1486
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001487 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1488 ((resultLen > 0) && (result == NULL)))
1489 return -1;
1490
1491 mutex_lock(&state->mutex);
1492 do {
1493 /* assume that the command register is ready
1494 since it is checked afterwards */
1495 u8 buffer[34];
1496 int cnt = 0, ii;
1497
Oliver Endrissebc7de22011-07-03 13:49:44 -03001498 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001499 buffer[cnt++] = (parameter[ii] & 0xFF);
1500 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1501 }
1502 buffer[cnt++] = (cmd & 0xFF);
1503 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1504
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001505 write_block(state, SCU_RAM_PARAM_0__A -
1506 (parameterLen - 1), cnt, buffer);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001507 /* Wait until SCU has processed command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001508 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001509 do {
1510 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001511 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001512 if (status < 0)
1513 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001514 } while (!(curCmd == DRX_SCU_READY)
1515 && (time_is_after_jiffies(end)));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001516 if (curCmd != DRX_SCU_READY) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001517 printk(KERN_ERR "drxk: SCU not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001518 mutex_unlock(&state->mutex);
1519 return -1;
1520 }
1521 /* read results */
1522 if ((resultLen > 0) && (result != NULL)) {
1523 s16 err;
1524 int ii;
1525
Oliver Endrissebc7de22011-07-03 13:49:44 -03001526 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001527 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001528 if (status < 0)
1529 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001530 }
1531
1532 /* Check if an error was reported by SCU */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001533 err = (s16) result[0];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001534
1535 /* check a few fixed error codes */
1536 if (err == SCU_RESULT_UNKSTD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001537 printk(KERN_ERR "drxk: SCU_RESULT_UNKSTD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001538 mutex_unlock(&state->mutex);
1539 return -1;
1540 } else if (err == SCU_RESULT_UNKCMD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001541 printk(KERN_ERR "drxk: SCU_RESULT_UNKCMD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001542 mutex_unlock(&state->mutex);
1543 return -1;
1544 }
1545 /* here it is assumed that negative means error,
1546 and positive no error */
1547 else if (err < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001548 printk(KERN_ERR "drxk: %s ERROR\n", __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001549 mutex_unlock(&state->mutex);
1550 return -1;
1551 }
1552 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001553 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001554 mutex_unlock(&state->mutex);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001555 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001556 printk(KERN_ERR "drxk: %s: status = %d\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001557
1558 return status;
1559}
1560
1561static int SetIqmAf(struct drxk_state *state, bool active)
1562{
1563 u16 data = 0;
1564 int status;
1565
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001566 dprintk(1, "\n");
1567
Oliver Endrissebc7de22011-07-03 13:49:44 -03001568 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001569 /* Configure IQM */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001570 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001571 if (status < 0)
1572 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001573 if (!active) {
1574 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1575 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1576 | IQM_AF_STDBY_STDBY_PD_STANDBY
1577 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
Oliver Endrissebc7de22011-07-03 13:49:44 -03001578 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1579 } else { /* active */
1580
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001581 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1582 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1583 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1584 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1585 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
Oliver Endrissebc7de22011-07-03 13:49:44 -03001586 );
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001587 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001588 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001589 if (status < 0)
1590 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001591 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001592 return status;
1593}
1594
Oliver Endrissebc7de22011-07-03 13:49:44 -03001595static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001596{
1597 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001598 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001599
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001600 dprintk(1, "\n");
1601
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001602 /* Check arguments */
1603 if (mode == NULL)
1604 return -1;
1605
1606 switch (*mode) {
1607 case DRX_POWER_UP:
1608 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1609 break;
1610 case DRXK_POWER_DOWN_OFDM:
1611 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1612 break;
1613 case DRXK_POWER_DOWN_CORE:
1614 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1615 break;
1616 case DRXK_POWER_DOWN_PLL:
1617 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1618 break;
1619 case DRX_POWER_DOWN:
1620 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1621 break;
1622 default:
1623 /* Unknow sleep mode */
1624 return -1;
1625 break;
1626 }
1627
1628 /* If already in requested power mode, do nothing */
1629 if (state->m_currentPowerMode == *mode)
1630 return 0;
1631
1632 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001633 if (state->m_currentPowerMode != DRX_POWER_UP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001634 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001635 status = PowerUpDevice(state);
1636 if (status < 0)
1637 break;
1638 status = DVBTEnableOFDMTokenRing(state, true);
1639 if (status < 0)
1640 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001641 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001642 }
1643
1644 if (*mode == DRX_POWER_UP) {
1645 /* Restore analog & pin configuartion */
1646 } else {
1647 /* Power down to requested mode */
1648 /* Backup some register settings */
1649 /* Set pins with possible pull-ups connected
1650 to them in input mode */
1651 /* Analog power down */
1652 /* ADC power down */
1653 /* Power down device */
1654 /* stop all comm_exec */
1655 /* Stop and power down previous standard */
1656 do {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001657 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001658 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001659 status = MPEGTSStop(state);
1660 if (status < 0)
1661 break;
1662 status = PowerDownDVBT(state, false);
1663 if (status < 0)
1664 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001665 break;
1666 case OM_QAM_ITU_A:
1667 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001668 status = MPEGTSStop(state);
1669 if (status < 0)
1670 break;
1671 status = PowerDownQAM(state);
1672 if (status < 0)
1673 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001674 break;
1675 default:
1676 break;
1677 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001678 status = DVBTEnableOFDMTokenRing(state, false);
1679 if (status < 0)
1680 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001681 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001682 if (status < 0)
1683 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001684 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001685 if (status < 0)
1686 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001687
Oliver Endrissebc7de22011-07-03 13:49:44 -03001688 if (*mode != DRXK_POWER_DOWN_OFDM) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001689 state->m_HICfgCtrl |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03001690 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001691 status = HI_CfgCommand(state);
1692 if (status < 0)
1693 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001694 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001695 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001696 }
1697 state->m_currentPowerMode = *mode;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001698 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001699}
1700
1701static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1702{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001703 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001704 u16 cmdResult = 0;
1705 u16 data = 0;
1706 int status;
1707
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001708 dprintk(1, "\n");
1709
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001710 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001711 status = read16(state, SCU_COMM_EXEC__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001712 if (status < 0)
1713 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001714 if (data == SCU_COMM_EXEC_ACTIVE) {
1715 /* Send OFDM stop command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001716 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
1717 if (status < 0)
1718 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001719 /* Send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001720 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1721 if (status < 0)
1722 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001723 }
1724
1725 /* Reset datapath for OFDM, processors first */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001726 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001727 if (status < 0)
1728 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001729 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_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, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001733 if (status < 0)
1734 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001735
1736 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001737 status = SetIqmAf(state, false);
1738 if (status < 0)
1739 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001740
1741 /* powerdown to OFDM mode */
1742 if (setPowerMode) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001743 status = CtrlPowerMode(state, &powerMode);
1744 if (status < 0)
1745 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001746 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001747 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001748 return status;
1749}
1750
Oliver Endrissebc7de22011-07-03 13:49:44 -03001751static int SetOperationMode(struct drxk_state *state,
1752 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001753{
1754 int status = 0;
1755
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001756 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001757 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001758 Stop and power down previous standard
1759 TODO investigate total power down instead of partial
1760 power down depending on "previous" standard.
1761 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001762 do {
1763 /* disable HW lock indicator */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001764 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001765 if (status < 0)
1766 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001767
1768 if (state->m_OperationMode != oMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001769 switch (state->m_OperationMode) {
1770 /* OM_NONE was added for start up */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001771 case OM_NONE:
1772 break;
1773 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001774 status = MPEGTSStop(state);
1775 if (status < 0)
1776 break;
1777 status = PowerDownDVBT(state, true);
1778 if (status < 0)
1779 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001780 state->m_OperationMode = OM_NONE;
1781 break;
1782 case OM_QAM_ITU_B:
1783 status = -1;
1784 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001785 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001786 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001787 status = MPEGTSStop(state);
1788 if (status < 0)
1789 break;
1790 status = PowerDownQAM(state);
1791 if (status < 0)
1792 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001793 state->m_OperationMode = OM_NONE;
1794 break;
1795 default:
1796 status = -1;
1797 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001798 status = status;
1799 if (status < 0)
1800 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001801
1802 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001803 Power up new standard
1804 */
1805 switch (oMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001806 case OM_DVBT:
1807 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001808 status = SetDVBTStandard(state, oMode);
1809 if (status < 0)
1810 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001811 break;
1812 case OM_QAM_ITU_B:
1813 status = -1;
1814 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001815 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001816 case OM_QAM_ITU_C:
1817 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001818 status = SetQAMStandard(state, oMode);
1819 if (status < 0)
1820 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001821 break;
1822 default:
1823 status = -1;
1824 }
1825 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001826 status = status;
1827 if (status < 0)
1828 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001829 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001830 return 0;
1831}
1832
1833static int Start(struct drxk_state *state, s32 offsetFreq,
1834 s32 IntermediateFrequency)
1835{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001836 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001837
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001838 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001839 do {
1840 u16 IFreqkHz;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001841 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001842
1843 if (state->m_DrxkState != DRXK_STOPPED &&
1844 state->m_DrxkState != DRXK_DTV_STARTED) {
1845 status = -1;
1846 break;
1847 }
1848 state->m_bMirrorFreqSpect =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001849 (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001850
1851 if (IntermediateFrequency < 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001852 state->m_bMirrorFreqSpect =
1853 !state->m_bMirrorFreqSpect;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001854 IntermediateFrequency = -IntermediateFrequency;
1855 }
1856
Oliver Endrissebc7de22011-07-03 13:49:44 -03001857 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001858 case OM_QAM_ITU_A:
1859 case OM_QAM_ITU_C:
1860 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001861 status = SetQAM(state, IFreqkHz, OffsetkHz);
1862 if (status < 0)
1863 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001864 state->m_DrxkState = DRXK_DTV_STARTED;
1865 break;
1866 case OM_DVBT:
1867 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001868 status = MPEGTSStop(state);
1869 if (status < 0)
1870 break;
1871 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1872 if (status < 0)
1873 break;
1874 status = DVBTStart(state);
1875 if (status < 0)
1876 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001877 state->m_DrxkState = DRXK_DTV_STARTED;
1878 break;
1879 default:
1880 break;
1881 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001882 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001883 return status;
1884}
1885
1886static int ShutDown(struct drxk_state *state)
1887{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001888 dprintk(1, "\n");
1889
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001890 MPEGTSStop(state);
1891 return 0;
1892}
1893
Oliver Endrissebc7de22011-07-03 13:49:44 -03001894static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1895 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001896{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001897 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001898
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001899 dprintk(1, "\n");
1900
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001901 if (pLockStatus == NULL)
1902 return -1;
1903
1904 *pLockStatus = NOT_LOCKED;
1905
1906 /* define the SCU command code */
1907 switch (state->m_OperationMode) {
1908 case OM_QAM_ITU_A:
1909 case OM_QAM_ITU_B:
1910 case OM_QAM_ITU_C:
1911 status = GetQAMLockStatus(state, pLockStatus);
1912 break;
1913 case OM_DVBT:
1914 status = GetDVBTLockStatus(state, pLockStatus);
1915 break;
1916 default:
1917 break;
1918 }
1919 return status;
1920}
1921
1922static int MPEGTSStart(struct drxk_state *state)
1923{
1924 int status = 0;
1925
1926 u16 fecOcSncMode = 0;
1927
1928 do {
1929 /* Allow OC to sync again */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001930 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001931 if (status < 0)
1932 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001933 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001934 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001935 if (status < 0)
1936 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001937 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001938 if (status < 0)
1939 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001940 } while (0);
1941 return status;
1942}
1943
1944static int MPEGTSDtoInit(struct drxk_state *state)
1945{
1946 int status = -1;
1947
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001948 dprintk(1, "\n");
1949
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001950 do {
1951 /* Rate integration settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001952 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001953 if (status < 0)
1954 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001955 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
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_GAIN__A, 0x000A);
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_AVR_PARM_A__A, 0x0008);
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_B__A, 0x0006);
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_TMD_HI_MARGIN__A, 0x0680);
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_LO_MARGIN__A, 0x0080);
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_COUNT__A, 0x03F4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001974 if (status < 0)
1975 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001976
1977 /* Additional configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001978 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001979 if (status < 0)
1980 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001981 status = write16(state, FEC_OC_SNC_LWM__A, 2);
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_HWM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001985 if (status < 0)
1986 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001987 } while (0);
1988 return status;
1989}
1990
Oliver Endrissebc7de22011-07-03 13:49:44 -03001991static int MPEGTSDtoSetup(struct drxk_state *state,
1992 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001993{
1994 int status = -1;
1995
Oliver Endrissebc7de22011-07-03 13:49:44 -03001996 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
1997 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
1998 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
1999 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2000 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2001 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2002 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002003 u16 fecOcTmdMode = 0;
2004 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002005 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002006 bool staticCLK = false;
2007
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002008 dprintk(1, "\n");
2009
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002010 do {
2011 /* Check insertion of the Reed-Solomon parity bytes */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002012 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002013 if (status < 0)
2014 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002015 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002016 if (status < 0)
2017 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002018 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002019 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2020 if (state->m_insertRSByte == true) {
2021 /* enable parity symbol forward */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002022 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002023 /* MVAL disable during parity bytes */
2024 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2025 /* TS burst length to 204 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002026 fecOcDtoBurstLen = 204;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002027 }
2028
2029 /* Check serial or parrallel output */
2030 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2031 if (state->m_enableParallel == false) {
2032 /* MPEG data output is serial -> set ipr_mode[0] */
2033 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2034 }
2035
2036 switch (oMode) {
2037 case OM_DVBT:
2038 maxBitRate = state->m_DVBTBitrate;
2039 fecOcTmdMode = 3;
2040 fecOcRcnCtlRate = 0xC00000;
2041 staticCLK = state->m_DVBTStaticCLK;
2042 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002043 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002044 case OM_QAM_ITU_C:
2045 fecOcTmdMode = 0x0004;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002046 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002047 maxBitRate = state->m_DVBCBitrate;
2048 staticCLK = state->m_DVBCStaticCLK;
2049 break;
2050 default:
2051 status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002052 } /* switch (standard) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002053 status = status;
2054 if (status < 0)
2055 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002056
2057 /* Configure DTO's */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002058 if (staticCLK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002059 u32 bitRate = 0;
2060
2061 /* Rational DTO for MCLK source (static MCLK rate),
2062 Dynamic DTO for optimal grouping
2063 (avoid intra-packet gaps),
2064 DTO offset enable to sync TS burst with MSTRT */
2065 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2066 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2067 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2068 FEC_OC_FCT_MODE_VIRT_ENA__M);
2069
2070 /* Check user defined bitrate */
2071 bitRate = maxBitRate;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002072 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002073 bitRate = 75900000UL;
2074 }
2075 /* Rational DTO period:
2076 dto_period = (Fsys / bitrate) - 2
2077
2078 Result should be floored,
2079 to make sure >= requested bitrate
Oliver Endrissebc7de22011-07-03 13:49:44 -03002080 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002081 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2082 * 1000) / bitRate);
2083 if (fecOcDtoPeriod <= 2)
2084 fecOcDtoPeriod = 0;
2085 else
2086 fecOcDtoPeriod -= 2;
2087 fecOcTmdIntUpdRate = 8;
2088 } else {
2089 /* (commonAttr->staticCLK == false) => dynamic mode */
2090 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2091 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2092 fecOcTmdIntUpdRate = 5;
2093 }
2094
2095 /* Write appropriate registers with requested configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002096 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002097 if (status < 0)
2098 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002099 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
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_MODE__A, fecOcDtoMode);
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_FCT_MODE__A, fecOcFctMode);
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_MODE__A, fecOcRegMode);
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_IPR_MODE__A, fecOcRegIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002112 if (status < 0)
2113 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002114
2115 /* Rate integration settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002116 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002117 if (status < 0)
2118 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002119 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
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_MODE__A, fecOcTmdMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002123 if (status < 0)
2124 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002125 } while (0);
2126 return status;
2127}
2128
2129static int MPEGTSConfigurePolarity(struct drxk_state *state)
2130{
2131 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002132 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002133
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002134 dprintk(1, "\n");
2135
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002136 /* Data mask for the output data byte */
2137 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002138 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2139 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2140 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2141 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002142
2143 /* Control selective inversion of output bits */
2144 fecOcRegIprInvert &= (~(InvertDataMask));
2145 if (state->m_invertDATA == true)
2146 fecOcRegIprInvert |= InvertDataMask;
2147 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2148 if (state->m_invertERR == true)
2149 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2150 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2151 if (state->m_invertSTR == true)
2152 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2153 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2154 if (state->m_invertVAL == true)
2155 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2156 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2157 if (state->m_invertCLK == true)
2158 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002159 status = write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002160 return status;
2161}
2162
2163#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2164
2165static int SetAgcRf(struct drxk_state *state,
2166 struct SCfgAgc *pAgcCfg, bool isDTV)
2167{
2168 int status = 0;
2169 struct SCfgAgc *pIfAgcSettings;
2170
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002171 dprintk(1, "\n");
2172
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002173 if (pAgcCfg == NULL)
2174 return -1;
2175
2176 do {
2177 u16 data = 0;
2178
2179 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002180 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002181
2182 /* Enable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002183 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002184 if (status < 0)
2185 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002186 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002187 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002188 if (status < 0)
2189 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002190
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002191 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002192 if (status < 0)
2193 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002194
2195 /* Enable SCU RF AGC loop */
2196 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2197
2198 /* Polarity */
2199 if (state->m_RfAgcPol)
2200 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2201 else
2202 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002203 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002204 if (status < 0)
2205 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002206
2207 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002208 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002209 if (status < 0)
2210 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002211
2212 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2213 data |= (~(pAgcCfg->speed <<
2214 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2215 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2216
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002217 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002218 if (status < 0)
2219 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002220
2221 if (IsDVBT(state))
2222 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2223 else if (IsQAM(state))
2224 pIfAgcSettings = &state->m_qamIfAgcCfg;
2225 else
2226 pIfAgcSettings = &state->m_atvIfAgcCfg;
2227 if (pIfAgcSettings == NULL)
2228 return -1;
2229
2230 /* Set TOP, only if IF-AGC is in AUTO mode */
2231 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002232 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002233 if (status < 0)
2234 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002235
2236 /* Cut-Off current */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002237 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002238 if (status < 0)
2239 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002240
2241 /* Max. output level */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002242 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002243 if (status < 0)
2244 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002245
2246 break;
2247
2248 case DRXK_AGC_CTRL_USER:
2249 /* Enable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002250 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002251 if (status < 0)
2252 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002253 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002254 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002255 if (status < 0)
2256 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002257
2258 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002259 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002260 if (status < 0)
2261 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002262 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2263 if (state->m_RfAgcPol)
2264 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2265 else
2266 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002267 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002268 if (status < 0)
2269 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002270
2271 /* SCU c.o.c. to 0, enabling full control range */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002272 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002273 if (status < 0)
2274 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002275
2276 /* Write value to output pin */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002277 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002278 if (status < 0)
2279 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002280 break;
2281
Oliver Endrissebc7de22011-07-03 13:49:44 -03002282 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002283 /* Disable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002284 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002285 if (status < 0)
2286 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002287 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002288 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002289 if (status < 0)
2290 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002291
2292 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002293 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002294 if (status < 0)
2295 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002296 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002297 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002298 if (status < 0)
2299 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002300 break;
2301
2302 default:
2303 return -1;
2304
Oliver Endrissebc7de22011-07-03 13:49:44 -03002305 } /* switch (agcsettings->ctrlMode) */
2306 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002307 return status;
2308}
2309
2310#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2311
Oliver Endrissebc7de22011-07-03 13:49:44 -03002312static int SetAgcIf(struct drxk_state *state,
2313 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002314{
2315 u16 data = 0;
2316 int status = 0;
2317 struct SCfgAgc *pRfAgcSettings;
2318
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002319 dprintk(1, "\n");
2320
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002321 do {
2322 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002323 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002324
2325 /* Enable IF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002326 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002327 if (status < 0)
2328 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002329 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002330 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002331 if (status < 0)
2332 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002333
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002334 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002335 if (status < 0)
2336 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002337
2338 /* Enable SCU IF AGC loop */
2339 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2340
2341 /* Polarity */
2342 if (state->m_IfAgcPol)
2343 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2344 else
2345 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002346 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002347 if (status < 0)
2348 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002349
2350 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002351 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002352 if (status < 0)
2353 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002354 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2355 data |= (~(pAgcCfg->speed <<
2356 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2357 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2358
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002359 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002360 if (status < 0)
2361 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002362
2363 if (IsQAM(state))
2364 pRfAgcSettings = &state->m_qamRfAgcCfg;
2365 else
2366 pRfAgcSettings = &state->m_atvRfAgcCfg;
2367 if (pRfAgcSettings == NULL)
2368 return -1;
2369 /* Restore TOP */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002370 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002371 if (status < 0)
2372 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002373 break;
2374
Oliver Endrissebc7de22011-07-03 13:49:44 -03002375 case DRXK_AGC_CTRL_USER:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002376
2377 /* Enable IF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002378 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002379 if (status < 0)
2380 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002381 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002382 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002383 if (status < 0)
2384 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002385
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002386 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002387 if (status < 0)
2388 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002389
2390 /* Disable SCU IF AGC loop */
2391 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2392
2393 /* Polarity */
2394 if (state->m_IfAgcPol)
2395 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2396 else
2397 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002398 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002399 if (status < 0)
2400 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002401
2402 /* Write value to output pin */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002403 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002404 if (status < 0)
2405 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002406 break;
2407
Oliver Endrissebc7de22011-07-03 13:49:44 -03002408 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002409
2410 /* Disable If AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002411 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002412 if (status < 0)
2413 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002414 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002415 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002416 if (status < 0)
2417 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002418
2419 /* Disable SCU IF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002420 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002421 if (status < 0)
2422 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002423 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002424 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002425 if (status < 0)
2426 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002427 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002428 } /* switch (agcSettingsIf->ctrlMode) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002429
2430 /* always set the top to support
2431 configurations without if-loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002432 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002433 if (status < 0)
2434 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002435
2436
Oliver Endrissebc7de22011-07-03 13:49:44 -03002437 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002438 return status;
2439}
2440
2441static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2442{
2443 u16 agcDacLvl;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002444 int status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002445
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002446 dprintk(1, "\n");
2447
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002448 *pValue = 0;
2449
Oliver Endrissebc7de22011-07-03 13:49:44 -03002450 if (status == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002451 u16 Level = 0;
2452 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2453 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2454 if (Level < 14000)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002455 *pValue = (14000 - Level) / 4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002456 else
2457 *pValue = 0;
2458 }
2459 return status;
2460}
2461
Oliver Endrissebc7de22011-07-03 13:49:44 -03002462static int GetQAMSignalToNoise(struct drxk_state *state,
2463 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002464{
2465 int status = 0;
2466
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002467 dprintk(1, "\n");
2468
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002469 do {
2470 /* MER calculation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002471 u16 qamSlErrPower = 0; /* accum. error between
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002472 raw and sliced symbols */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002473 u32 qamSlSigPower = 0; /* used for MER, depends of
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002474 QAM constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002475 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002476
2477 /* get the register value needed for MER */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002478 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002479 if (status < 0)
2480 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002481
Oliver Endrissebc7de22011-07-03 13:49:44 -03002482 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002483 case QAM_16:
2484 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2485 break;
2486 case QAM_32:
2487 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2488 break;
2489 case QAM_64:
2490 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2491 break;
2492 case QAM_128:
2493 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2494 break;
2495 default:
2496 case QAM_256:
2497 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2498 break;
2499 }
2500
2501 if (qamSlErrPower > 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002502 qamSlMer = Log10Times100(qamSlSigPower) -
2503 Log10Times100((u32) qamSlErrPower);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002504 }
2505 *pSignalToNoise = qamSlMer;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002506 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002507 return status;
2508}
2509
Oliver Endrissebc7de22011-07-03 13:49:44 -03002510static int GetDVBTSignalToNoise(struct drxk_state *state,
2511 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002512{
2513 int status = 0;
2514
Oliver Endrissebc7de22011-07-03 13:49:44 -03002515 u16 regData = 0;
2516 u32 EqRegTdSqrErrI = 0;
2517 u32 EqRegTdSqrErrQ = 0;
2518 u16 EqRegTdSqrErrExp = 0;
2519 u16 EqRegTdTpsPwrOfs = 0;
2520 u16 EqRegTdReqSmbCnt = 0;
2521 u32 tpsCnt = 0;
2522 u32 SqrErrIQ = 0;
2523 u32 a = 0;
2524 u32 b = 0;
2525 u32 c = 0;
2526 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002527 u16 transmissionParams = 0;
2528
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002529 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002530 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002531 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002532 if (status < 0)
2533 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002534 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
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_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
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_I__A, &regData);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002541 if (status < 0)
2542 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002543 /* Extend SQR_ERR_I operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002544 EqRegTdSqrErrI = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002545 if ((EqRegTdSqrErrExp > 11) &&
2546 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2547 EqRegTdSqrErrI += 0x00010000UL;
2548 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002549 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002550 if (status < 0)
2551 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002552 /* Extend SQR_ERR_Q operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002553 EqRegTdSqrErrQ = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002554 if ((EqRegTdSqrErrExp > 11) &&
2555 (EqRegTdSqrErrQ < 0x00000FFFUL))
2556 EqRegTdSqrErrQ += 0x00010000UL;
2557
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002558 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002559 if (status < 0)
2560 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002561
2562 /* Check input data for MER */
2563
2564 /* MER calculation (in 0.1 dB) without math.h */
2565 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2566 iMER = 0;
2567 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2568 /* No error at all, this must be the HW reset value
2569 * Apparently no first measurement yet
2570 * Set MER to 0.0 */
2571 iMER = 0;
2572 } else {
2573 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03002574 EqRegTdSqrErrExp;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002575 if ((transmissionParams &
2576 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2577 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2578 tpsCnt = 17;
2579 else
2580 tpsCnt = 68;
2581
2582 /* IMER = 100 * log10 (x)
2583 where x = (EqRegTdTpsPwrOfs^2 *
2584 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2585
2586 => IMER = a + b -c
2587 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2588 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2589 c = 100 * log10 (SqrErrIQ)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002590 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002591
2592 /* log(x) x = 9bits * 9bits->18 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002593 a = Log10Times100(EqRegTdTpsPwrOfs *
2594 EqRegTdTpsPwrOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002595 /* log(x) x = 16bits * 7bits->23 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002596 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002597 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2598 c = Log10Times100(SqrErrIQ);
2599
2600 iMER = a + b;
2601 /* No negative MER, clip to zero */
2602 if (iMER > c)
2603 iMER -= c;
2604 else
2605 iMER = 0;
2606 }
2607 *pSignalToNoise = iMER;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002608 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002609
2610 return status;
2611}
2612
2613static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2614{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002615 dprintk(1, "\n");
2616
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002617 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002618 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002619 case OM_DVBT:
2620 return GetDVBTSignalToNoise(state, pSignalToNoise);
2621 case OM_QAM_ITU_A:
2622 case OM_QAM_ITU_C:
2623 return GetQAMSignalToNoise(state, pSignalToNoise);
2624 default:
2625 break;
2626 }
2627 return 0;
2628}
2629
2630#if 0
2631static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2632{
2633 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2634 int status = 0;
2635
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002636 dprintk(1, "\n");
2637
Oliver Endrissebc7de22011-07-03 13:49:44 -03002638 static s32 QE_SN[] = {
2639 51, /* QPSK 1/2 */
2640 69, /* QPSK 2/3 */
2641 79, /* QPSK 3/4 */
2642 89, /* QPSK 5/6 */
2643 97, /* QPSK 7/8 */
2644 108, /* 16-QAM 1/2 */
2645 131, /* 16-QAM 2/3 */
2646 146, /* 16-QAM 3/4 */
2647 156, /* 16-QAM 5/6 */
2648 160, /* 16-QAM 7/8 */
2649 165, /* 64-QAM 1/2 */
2650 187, /* 64-QAM 2/3 */
2651 202, /* 64-QAM 3/4 */
2652 216, /* 64-QAM 5/6 */
2653 225, /* 64-QAM 7/8 */
2654 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002655
2656 *pQuality = 0;
2657
2658 do {
2659 s32 SignalToNoise = 0;
2660 u16 Constellation = 0;
2661 u16 CodeRate = 0;
2662 u32 SignalToNoiseRel;
2663 u32 BERQuality;
2664
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002665 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2666 if (status < 0)
2667 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002668 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002669 if (status < 0)
2670 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002671 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2672
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002673 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002674 if (status < 0)
2675 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002676 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2677
2678 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2679 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2680 break;
2681 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002682 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002683 BERQuality = 100;
2684
Oliver Endrissebc7de22011-07-03 13:49:44 -03002685 if (SignalToNoiseRel < -70)
2686 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002687 else if (SignalToNoiseRel < 30)
2688 *pQuality = ((SignalToNoiseRel + 70) *
2689 BERQuality) / 100;
2690 else
2691 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002692 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002693 return 0;
2694};
2695
Oliver Endrissebc7de22011-07-03 13:49:44 -03002696static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002697{
2698 int status = 0;
2699 *pQuality = 0;
2700
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002701 dprintk(1, "\n");
2702
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002703 do {
2704 u32 SignalToNoise = 0;
2705 u32 BERQuality = 100;
2706 u32 SignalToNoiseRel = 0;
2707
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002708 status = GetQAMSignalToNoise(state, &SignalToNoise);
2709 if (status < 0)
2710 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002711
Oliver Endrissebc7de22011-07-03 13:49:44 -03002712 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002713 case QAM_16:
2714 SignalToNoiseRel = SignalToNoise - 200;
2715 break;
2716 case QAM_32:
2717 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002718 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002719 case QAM_64:
2720 SignalToNoiseRel = SignalToNoise - 260;
2721 break;
2722 case QAM_128:
2723 SignalToNoiseRel = SignalToNoise - 290;
2724 break;
2725 default:
2726 case QAM_256:
2727 SignalToNoiseRel = SignalToNoise - 320;
2728 break;
2729 }
2730
2731 if (SignalToNoiseRel < -70)
2732 *pQuality = 0;
2733 else if (SignalToNoiseRel < 30)
2734 *pQuality = ((SignalToNoiseRel + 70) *
2735 BERQuality) / 100;
2736 else
2737 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002738 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002739
2740 return status;
2741}
2742
2743static int GetQuality(struct drxk_state *state, s32 *pQuality)
2744{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002745 dprintk(1, "\n");
2746
Oliver Endrissebc7de22011-07-03 13:49:44 -03002747 switch (state->m_OperationMode) {
2748 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002749 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002750 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002751 return GetDVBCQuality(state, pQuality);
2752 default:
2753 break;
2754 }
2755
2756 return 0;
2757}
2758#endif
2759
2760/* Free data ram in SIO HI */
2761#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2762#define SIO_HI_RA_RAM_USR_END__A 0x420060
2763
2764#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2765#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2766#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2767#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2768
2769#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2770#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2771#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2772
2773static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2774{
2775 int status;
2776
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002777 dprintk(1, "\n");
2778
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002779 if (state->m_DrxkState == DRXK_UNINITIALIZED)
2780 return -1;
2781 if (state->m_DrxkState == DRXK_POWERED_DOWN)
2782 return -1;
2783
2784 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002785 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 -03002786 if (status < 0)
2787 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002788 if (bEnableBridge) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002789 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 -03002790 if (status < 0)
2791 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002792 } else {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002793 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 -03002794 if (status < 0)
2795 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002796 }
2797
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002798 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2799 if (status < 0)
2800 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002801 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002802 return status;
2803}
2804
Oliver Endrissebc7de22011-07-03 13:49:44 -03002805static int SetPreSaw(struct drxk_state *state,
2806 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002807{
2808 int status;
2809
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002810 dprintk(1, "\n");
2811
Oliver Endrissebc7de22011-07-03 13:49:44 -03002812 if ((pPreSawCfg == NULL)
2813 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002814 return -1;
2815
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002816 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002817 return status;
2818}
2819
2820static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002821 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002822{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002823 u16 blStatus = 0;
2824 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2825 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2826 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002827 unsigned long end;
2828
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002829 dprintk(1, "\n");
2830
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002831 mutex_lock(&state->mutex);
2832 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002833 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002834 if (status < 0)
2835 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002836 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002837 if (status < 0)
2838 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002839 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002840 if (status < 0)
2841 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002842 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002843 if (status < 0)
2844 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002845 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002846 if (status < 0)
2847 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002848 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002849 if (status < 0)
2850 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002851
Oliver Endrissebc7de22011-07-03 13:49:44 -03002852 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002853 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002854 status = read16(state, SIO_BL_STATUS__A, &blStatus);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002855 if (status < 0)
2856 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002857 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002858 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03002859 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002860 mutex_unlock(&state->mutex);
2861 return -1;
2862 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03002863 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002864 mutex_unlock(&state->mutex);
2865 return status;
2866
2867}
2868
Oliver Endrissebc7de22011-07-03 13:49:44 -03002869static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002870{
2871 u16 data = 0;
2872 int status;
2873
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002874 dprintk(1, "\n");
2875
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002876 do {
2877 /* Start measurement */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002878 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002879 if (status < 0)
2880 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002881 status = write16(state, IQM_AF_START_LOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002882 if (status < 0)
2883 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002884
2885 *count = 0;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002886 status = read16(state, IQM_AF_PHASE0__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002887 if (status < 0)
2888 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002889 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002890 *count = *count + 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002891 status = read16(state, IQM_AF_PHASE1__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_PHASE2__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;
2901 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002902 return status;
2903}
2904
2905static int ADCSynchronization(struct drxk_state *state)
2906{
2907 u16 count = 0;
2908 int status;
2909
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002910 dprintk(1, "\n");
2911
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002912 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002913 status = ADCSyncMeasurement(state, &count);
2914 if (status < 0)
2915 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002916
Oliver Endrissebc7de22011-07-03 13:49:44 -03002917 if (count == 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002918 /* Try sampling on a diffrent edge */
2919 u16 clkNeg = 0;
2920
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002921 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002922 if (status < 0)
2923 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002924 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002925 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2926 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2927 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002928 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002929 } else {
2930 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2931 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002932 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002933 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002934 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002935 if (status < 0)
2936 break;
2937 status = ADCSyncMeasurement(state, &count);
2938 if (status < 0)
2939 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002940 }
2941
2942 if (count < 2)
2943 status = -1;
2944 } while (0);
2945 return status;
2946}
2947
2948static int SetFrequencyShifter(struct drxk_state *state,
2949 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002950 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002951{
2952 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002953 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002954 u32 fmFrequencyShift = 0;
2955 bool tunerMirror = !state->m_bMirrorFreqSpect;
2956 u32 adcFreq;
2957 bool adcFlip;
2958 int status;
2959 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002960 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002961 u32 frequencyShift;
2962 bool imageToSelect;
2963
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002964 dprintk(1, "\n");
2965
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002966 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03002967 Program frequency shifter
2968 No need to account for mirroring on RF
2969 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002970 if (isDTV) {
2971 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
2972 (state->m_OperationMode == OM_QAM_ITU_C) ||
2973 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03002974 selectPosImage = true;
2975 else
2976 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002977 }
2978 if (tunerMirror)
2979 /* tuner doesn't mirror */
2980 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03002981 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002982 else
2983 /* tuner mirrors */
2984 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002985 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002986 if (ifFreqActual > samplingFrequency / 2) {
2987 /* adc mirrors */
2988 adcFreq = samplingFrequency - ifFreqActual;
2989 adcFlip = true;
2990 } else {
2991 /* adc doesn't mirror */
2992 adcFreq = ifFreqActual;
2993 adcFlip = false;
2994 }
2995
2996 frequencyShift = adcFreq;
2997 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03002998 adcFlip ^ selectPosImage;
2999 state->m_IqmFsRateOfs =
3000 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003001
3002 if (imageToSelect)
3003 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3004
3005 /* Program frequency shifter with tuner offset compensation */
3006 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003007 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3008 state->m_IqmFsRateOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003009 return status;
3010}
3011
3012static int InitAGC(struct drxk_state *state, bool isDTV)
3013{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003014 u16 ingainTgt = 0;
3015 u16 ingainTgtMin = 0;
3016 u16 ingainTgtMax = 0;
3017 u16 clpCyclen = 0;
3018 u16 clpSumMin = 0;
3019 u16 clpDirTo = 0;
3020 u16 snsSumMin = 0;
3021 u16 snsSumMax = 0;
3022 u16 clpSumMax = 0;
3023 u16 snsDirTo = 0;
3024 u16 kiInnergainMin = 0;
3025 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003026 u16 ifIaccuHiTgtMin = 0;
3027 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003028 u16 data = 0;
3029 u16 fastClpCtrlDelay = 0;
3030 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003031 int status = 0;
3032
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003033 dprintk(1, "\n");
3034
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003035 do {
3036 /* Common settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003037 snsSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003038 ifIaccuHiTgtMin = 2047;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003039 clpCyclen = 500;
3040 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003041
3042 if (IsQAM(state)) {
3043 /* Standard specific settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003044 clpSumMin = 8;
3045 clpDirTo = (u16) -9;
3046 clpCtrlMode = 0;
3047 snsSumMin = 8;
3048 snsDirTo = (u16) -9;
3049 kiInnergainMin = (u16) -1030;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003050 } else
3051 status = -1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003052 status = (status);
3053 if (status < 0)
3054 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003055 if (IsQAM(state)) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003056 ifIaccuHiTgtMax = 0x2380;
3057 ifIaccuHiTgt = 0x2380;
3058 ingainTgtMin = 0x0511;
3059 ingainTgt = 0x0511;
3060 ingainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003061 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003062 state->m_qamIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003063 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003064 ifIaccuHiTgtMax = 0x1200;
3065 ifIaccuHiTgt = 0x1200;
3066 ingainTgtMin = 13424;
3067 ingainTgt = 13424;
3068 ingainTgtMax = 30000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003069 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003070 state->m_dvbtIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003071 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003072 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003073 if (status < 0)
3074 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003075
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003076 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003077 if (status < 0)
3078 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003079 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003080 if (status < 0)
3081 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003082 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003083 if (status < 0)
3084 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003085 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003086 if (status < 0)
3087 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003088 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003089 if (status < 0)
3090 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003091 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003092 if (status < 0)
3093 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003094 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003095 if (status < 0)
3096 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003097 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003098 if (status < 0)
3099 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003100 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003101 if (status < 0)
3102 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003103 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003104 if (status < 0)
3105 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003106 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003107 if (status < 0)
3108 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003109 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003110 if (status < 0)
3111 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003112
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003113 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003114 if (status < 0)
3115 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003116 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003117 if (status < 0)
3118 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003119 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003120 if (status < 0)
3121 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003122
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003123 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003124 if (status < 0)
3125 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003126 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003127 if (status < 0)
3128 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003129 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003130 if (status < 0)
3131 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003132
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003133 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003134 if (status < 0)
3135 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003136 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003137 if (status < 0)
3138 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003139 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003140 if (status < 0)
3141 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003142 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003143 if (status < 0)
3144 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003145 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003146 if (status < 0)
3147 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003148 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003149 if (status < 0)
3150 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003151 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003152 if (status < 0)
3153 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003154 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003155 if (status < 0)
3156 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003157 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003158 if (status < 0)
3159 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003160 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003161 if (status < 0)
3162 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003163 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003164 if (status < 0)
3165 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003166 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003167 if (status < 0)
3168 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003169 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003170 if (status < 0)
3171 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003172 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003173 if (status < 0)
3174 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003175 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003176 if (status < 0)
3177 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003178 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003179 if (status < 0)
3180 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003181 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003182 if (status < 0)
3183 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003184 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003185 if (status < 0)
3186 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003187 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003188 if (status < 0)
3189 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003190
3191 /* Initialize inner-loop KI gain factors */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003192 status = read16(state, SCU_RAM_AGC_KI__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003193 if (status < 0)
3194 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003195 if (IsQAM(state)) {
3196 data = 0x0657;
3197 data &= ~SCU_RAM_AGC_KI_RF__M;
3198 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3199 data &= ~SCU_RAM_AGC_KI_IF__M;
3200 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3201 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003202 status = write16(state, SCU_RAM_AGC_KI__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003203 if (status < 0)
3204 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003205 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003206 return status;
3207}
3208
Oliver Endrissebc7de22011-07-03 13:49:44 -03003209static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003210{
3211 int status;
3212
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003213 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003214 do {
3215 if (packetErr == NULL) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003216 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003217 if (status < 0)
3218 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003219 } else {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003220 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003221 if (status < 0)
3222 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003223 }
3224 } while (0);
3225 return status;
3226}
3227
3228static int DVBTScCommand(struct drxk_state *state,
3229 u16 cmd, u16 subcmd,
3230 u16 param0, u16 param1, u16 param2,
3231 u16 param3, u16 param4)
3232{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003233 u16 curCmd = 0;
3234 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003235 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003236 u16 scExec = 0;
3237 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003238
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003239 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003240 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003241 if (scExec != 1) {
3242 /* SC is not running */
3243 return -1;
3244 }
3245
3246 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003247 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003248 do {
3249 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003250 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003251 retryCnt++;
3252 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
3253 if (retryCnt >= DRXK_MAX_RETRIES)
3254 return -1;
3255 /* Write sub-command */
3256 switch (cmd) {
3257 /* All commands using sub-cmd */
3258 case OFDM_SC_RA_RAM_CMD_PROC_START:
3259 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3260 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003261 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003262 write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003263 break;
3264 default:
3265 /* Do nothing */
3266 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003267 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003268
3269 /* Write needed parameters and the command */
3270 switch (cmd) {
3271 /* All commands using 5 parameters */
3272 /* All commands using 4 parameters */
3273 /* All commands using 3 parameters */
3274 /* All commands using 2 parameters */
3275 case OFDM_SC_RA_RAM_CMD_PROC_START:
3276 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3277 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003278 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003279 write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003280 /* All commands using 1 parameters */
3281 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3282 case OFDM_SC_RA_RAM_CMD_USER_IO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003283 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003284 write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003285 /* All commands using 0 parameters */
3286 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3287 case OFDM_SC_RA_RAM_CMD_NULL:
3288 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003289 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003290 break;
3291 default:
3292 /* Unknown command */
3293 return -EINVAL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003294 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003295
3296 /* Wait until sc is ready processing command */
3297 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003298 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003299 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003300 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003301 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003302 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003303 if (retryCnt >= DRXK_MAX_RETRIES)
3304 return -1;
3305
3306 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003307 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003308 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003309 /* illegal command */
3310 return -EINVAL;
3311 }
3312
3313 /* Retreive results parameters from SC */
3314 switch (cmd) {
3315 /* All commands yielding 5 results */
3316 /* All commands yielding 4 results */
3317 /* All commands yielding 3 results */
3318 /* All commands yielding 2 results */
3319 /* All commands yielding 1 result */
3320 case OFDM_SC_RA_RAM_CMD_USER_IO:
3321 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003322 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003323 read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003324 /* All commands yielding 0 results */
3325 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3326 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3327 case OFDM_SC_RA_RAM_CMD_PROC_START:
3328 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3329 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3330 case OFDM_SC_RA_RAM_CMD_NULL:
3331 break;
3332 default:
3333 /* Unknown command */
3334 return -EINVAL;
3335 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003336 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003337 return status;
3338}
3339
Oliver Endrissebc7de22011-07-03 13:49:44 -03003340static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003341{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003342 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003343 int status;
3344
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003345 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003346 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003347 status = CtrlPowerMode(state, &powerMode);
3348 if (status < 0)
3349 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003350 } while (0);
3351 return status;
3352}
3353
Oliver Endrissebc7de22011-07-03 13:49:44 -03003354static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003355{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003356 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003357
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003358 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003359 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003360 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003361 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003362 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003363
3364 return status;
3365}
3366
3367#define DEFAULT_FR_THRES_8K 4000
3368static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3369{
3370
3371 int status;
3372
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003373 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003374 if (*enabled == true) {
3375 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003376 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003377 DEFAULT_FR_THRES_8K);
3378 } else {
3379 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003380 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003381 }
3382
3383 return status;
3384}
3385
3386static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3387 struct DRXKCfgDvbtEchoThres_t *echoThres)
3388{
3389 u16 data = 0;
3390 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003391
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003392 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003393 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003394 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003395 if (status < 0)
3396 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003397
Oliver Endrissebc7de22011-07-03 13:49:44 -03003398 switch (echoThres->fftMode) {
3399 case DRX_FFTMODE_2K:
3400 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3401 data |=
3402 ((echoThres->threshold <<
3403 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3404 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3405 break;
3406 case DRX_FFTMODE_8K:
3407 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3408 data |=
3409 ((echoThres->threshold <<
3410 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3411 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3412 break;
3413 default:
3414 return -1;
3415 break;
3416 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003417
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003418 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003419 if (status < 0)
3420 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003421 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003422
Oliver Endrissebc7de22011-07-03 13:49:44 -03003423 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003424}
3425
3426static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003427 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003428{
3429 int status;
3430
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003431 dprintk(1, "\n");
3432
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003433 switch (*speed) {
3434 case DRXK_DVBT_SQI_SPEED_FAST:
3435 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3436 case DRXK_DVBT_SQI_SPEED_SLOW:
3437 break;
3438 default:
3439 return -EINVAL;
3440 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003441 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003442 (u16) *speed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003443 return status;
3444}
3445
3446/*============================================================================*/
3447
3448/**
3449* \brief Activate DVBT specific presets
3450* \param demod instance of demodulator.
3451* \return DRXStatus_t.
3452*
3453* Called in DVBTSetStandard
3454*
3455*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003456static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003457{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003458 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003459
Oliver Endrissebc7de22011-07-03 13:49:44 -03003460 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3461 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003462
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003463 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003464 do {
3465 bool setincenable = false;
3466 bool setfrenable = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003467 status = DVBTCtrlSetIncEnable(state, &setincenable);
3468 if (status < 0)
3469 break;
3470 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3471 if (status < 0)
3472 break;
3473 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3474 if (status < 0)
3475 break;
3476 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3477 if (status < 0)
3478 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003479 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003480 if (status < 0)
3481 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003482 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003483
Oliver Endrissebc7de22011-07-03 13:49:44 -03003484 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003485}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003486
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003487/*============================================================================*/
3488
3489/**
3490* \brief Initialize channelswitch-independent settings for DVBT.
3491* \param demod instance of demodulator.
3492* \return DRXStatus_t.
3493*
3494* For ROM code channel filter taps are loaded from the bootloader. For microcode
3495* the DVB-T taps from the drxk_filters.h are used.
3496*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003497static int SetDVBTStandard(struct drxk_state *state,
3498 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003499{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003500 u16 cmdResult = 0;
3501 u16 data = 0;
3502 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003503
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003504 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003505
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003506 PowerUpDVBT(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003507 do {
3508 /* added antenna switch */
3509 SwitchAntennaToDVBT(state);
3510 /* send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003511 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
3512 if (status < 0)
3513 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003514
3515 /* send OFDM setenv command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003516 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3517 if (status < 0)
3518 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003519
3520 /* reset datapath for OFDM, processors first */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003521 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003522 if (status < 0)
3523 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003524 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003525 if (status < 0)
3526 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003527 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003528 if (status < 0)
3529 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003530
3531 /* IQM setup */
3532 /* synchronize on ofdstate->m_festart */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003533 status = write16(state, IQM_AF_UPD_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003534 if (status < 0)
3535 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003536 /* window size for clipping ADC detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003537 status = write16(state, IQM_AF_CLP_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003538 if (status < 0)
3539 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003540 /* window size for for sense pre-SAW detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003541 status = write16(state, IQM_AF_SNS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003542 if (status < 0)
3543 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003544 /* sense threshold for sense pre-SAW detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003545 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003546 if (status < 0)
3547 break;
3548 status = SetIqmAf(state, true);
3549 if (status < 0)
3550 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003551
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003552 status = write16(state, IQM_AF_AGC_RF__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003553 if (status < 0)
3554 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003555
3556 /* Impulse noise cruncher setup */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003557 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003558 if (status < 0)
3559 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003560 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003561 if (status < 0)
3562 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003563 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003564 if (status < 0)
3565 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003566
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003567 status = write16(state, IQM_RC_STRETCH__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003568 if (status < 0)
3569 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003570 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003571 if (status < 0)
3572 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003573 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003574 if (status < 0)
3575 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003576 status = write16(state, IQM_CF_SCALE__A, 1600);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003577 if (status < 0)
3578 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003579 status = write16(state, IQM_CF_SCALE_SH__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003580 if (status < 0)
3581 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003582
3583 /* virtual clipping threshold for clipping ADC detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003584 status = write16(state, IQM_AF_CLP_TH__A, 448);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003585 if (status < 0)
3586 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003587 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003588 if (status < 0)
3589 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003590
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003591 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3592 if (status < 0)
3593 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003594
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003595 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003596 if (status < 0)
3597 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003598 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003599 if (status < 0)
3600 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003601 /* enable power measurement interrupt */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003602 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003603 if (status < 0)
3604 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003605 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003606 if (status < 0)
3607 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003608
3609 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003610 status = ADCSynchronization(state);
3611 if (status < 0)
3612 break;
3613 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3614 if (status < 0)
3615 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003616
3617 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003618 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003619 if (status < 0)
3620 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003621
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003622 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3623 if (status < 0)
3624 break;
3625 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3626 if (status < 0)
3627 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003628
3629 /* Set Noise Estimation notch width and enable DC fix */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003630 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003631 if (status < 0)
3632 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003633 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003634 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003635 if (status < 0)
3636 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003637
3638 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003639 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003640 if (status < 0)
3641 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003642
Oliver Endrissebc7de22011-07-03 13:49:44 -03003643 if (!state->m_DRXK_A3_ROM_CODE) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003644 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003645 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003646 if (status < 0)
3647 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003648 }
3649
3650 /* OFDM_SC setup */
3651#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003652 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003653 if (status < 0)
3654 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003655 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003656 if (status < 0)
3657 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003658#endif
3659
3660 /* FEC setup */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003661 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003662 if (status < 0)
3663 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003664
3665
3666#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003667 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003668 if (status < 0)
3669 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003670#else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003671 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003672 if (status < 0)
3673 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003674#endif
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003675 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003676 if (status < 0)
3677 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003678
3679 /* Setup MPEG bus */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003680 status = MPEGTSDtoSetup(state, OM_DVBT);
3681 if (status < 0)
3682 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003683 /* Set DVBT Presets */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003684 status = DVBTActivatePresets(state);
3685 if (status < 0)
3686 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003687
3688 } while (0);
3689
Oliver Endrissebc7de22011-07-03 13:49:44 -03003690 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003691 printk(KERN_ERR "drxk: %s status - %08x\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003692
3693 return status;
3694}
3695
3696/*============================================================================*/
3697/**
3698* \brief Start dvbt demodulating for channel.
3699* \param demod instance of demodulator.
3700* \return DRXStatus_t.
3701*/
3702static int DVBTStart(struct drxk_state *state)
3703{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003704 u16 param1;
3705 int status;
3706 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003707
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003708 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003709 /* Start correct processes to get in lock */
3710 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
3711 do {
3712 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003713 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3714 if (status < 0)
3715 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003716 /* Start FEC OC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003717 status = MPEGTSStart(state);
3718 if (status < 0)
3719 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003720 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003721 if (status < 0)
3722 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003723 } while (0);
3724 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003725}
3726
3727
3728/*============================================================================*/
3729
3730/**
3731* \brief Set up dvbt demodulator for channel.
3732* \param demod instance of demodulator.
3733* \return DRXStatus_t.
3734* // original DVBTSetChannel()
3735*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003736static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3737 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003738{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003739 u16 cmdResult = 0;
3740 u16 transmissionParams = 0;
3741 u16 operationMode = 0;
3742 u32 iqmRcRateOfs = 0;
3743 u32 bandwidth = 0;
3744 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003745 int status;
3746
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003747 dprintk(1, "\n");
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003748 /* printk(KERN_DEBUG "drxk: %s IF =%d, TFO = %d\n", __func__, IntermediateFreqkHz, tunerFreqOffset); */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003749 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003750 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3751 if (status < 0)
3752 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003753
3754 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003755 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003756 if (status < 0)
3757 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003758
3759 /* Stop processors */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003760 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003761 if (status < 0)
3762 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003763 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003764 if (status < 0)
3765 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003766
3767 /* Mandatory fix, always stop CP, required to set spl offset back to
3768 hardware default (is set to 0 by ucode during pilot detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003769 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003770 if (status < 0)
3771 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003772
3773 /*== Write channel settings to device =====================================*/
3774
3775 /* mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003776 switch (state->param.u.ofdm.transmission_mode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003777 case TRANSMISSION_MODE_AUTO:
3778 default:
3779 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3780 /* fall through , try first guess DRX_FFTMODE_8K */
3781 case TRANSMISSION_MODE_8K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003782 transmissionParams |=
3783 OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003784 break;
3785 case TRANSMISSION_MODE_2K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003786 transmissionParams |=
3787 OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003788 break;
3789 }
3790
3791 /* guard */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003792 switch (state->param.u.ofdm.guard_interval) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003793 default:
3794 case GUARD_INTERVAL_AUTO:
3795 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3796 /* fall through , try first guess DRX_GUARD_1DIV4 */
3797 case GUARD_INTERVAL_1_4:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003798 transmissionParams |=
3799 OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003800 break;
3801 case GUARD_INTERVAL_1_32:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003802 transmissionParams |=
3803 OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003804 break;
3805 case GUARD_INTERVAL_1_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003806 transmissionParams |=
3807 OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003808 break;
3809 case GUARD_INTERVAL_1_8:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003810 transmissionParams |=
3811 OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003812 break;
3813 }
3814
3815 /* hierarchy */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003816 switch (state->param.u.ofdm.hierarchy_information) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003817 case HIERARCHY_AUTO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003818 case HIERARCHY_NONE:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003819 default:
3820 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3821 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003822 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3823 /* break; */
3824 case HIERARCHY_1:
3825 transmissionParams |=
3826 OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003827 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003828 case HIERARCHY_2:
3829 transmissionParams |=
3830 OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003831 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003832 case HIERARCHY_4:
3833 transmissionParams |=
3834 OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003835 break;
3836 }
3837
3838
3839 /* constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003840 switch (state->param.u.ofdm.constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003841 case QAM_AUTO:
3842 default:
3843 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3844 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3845 case QAM_64:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003846 transmissionParams |=
3847 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003848 break;
3849 case QPSK:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003850 transmissionParams |=
3851 OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003852 break;
3853 case QAM_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003854 transmissionParams |=
3855 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003856 break;
3857 }
3858#if 0
Oliver Endrissebc7de22011-07-03 13:49:44 -03003859 /* No hierachical channels support in BDA */
3860 /* Priority (only for hierarchical channels) */
3861 switch (channel->priority) {
3862 case DRX_PRIORITY_LOW:
3863 transmissionParams |=
3864 OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3865 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3866 OFDM_EC_SB_PRIOR_LO);
3867 break;
3868 case DRX_PRIORITY_HIGH:
3869 transmissionParams |=
3870 OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3871 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3872 OFDM_EC_SB_PRIOR_HI));
3873 break;
3874 case DRX_PRIORITY_UNKNOWN: /* fall through */
3875 default:
3876 return DRX_STS_INVALID_ARG;
3877 break;
3878 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003879#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03003880 /* Set Priorty high */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003881 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003882 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003883 if (status < 0)
3884 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003885#endif
3886
3887 /* coderate */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003888 switch (state->param.u.ofdm.code_rate_HP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003889 case FEC_AUTO:
3890 default:
3891 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3892 /* fall through , try first guess DRX_CODERATE_2DIV3 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003893 case FEC_2_3:
3894 transmissionParams |=
3895 OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003896 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003897 case FEC_1_2:
3898 transmissionParams |=
3899 OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003900 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003901 case FEC_3_4:
3902 transmissionParams |=
3903 OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003904 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003905 case FEC_5_6:
3906 transmissionParams |=
3907 OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003908 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003909 case FEC_7_8:
3910 transmissionParams |=
3911 OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003912 break;
3913 }
3914
3915 /* SAW filter selection: normaly not necesarry, but if wanted
3916 the application can select a SAW filter via the driver by using UIOs */
3917 /* First determine real bandwidth (Hz) */
3918 /* Also set delay for impulse noise cruncher */
3919 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3920 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3921 functions */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003922 switch (state->param.u.ofdm.bandwidth) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003923 case BANDWIDTH_AUTO:
3924 case BANDWIDTH_8_MHZ:
3925 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003926 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003927 if (status < 0)
3928 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003929 /* cochannel protection for PAL 8 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003930 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003931 if (status < 0)
3932 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003933 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003934 if (status < 0)
3935 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003936 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003937 if (status < 0)
3938 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003939 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003940 if (status < 0)
3941 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003942 break;
3943 case BANDWIDTH_7_MHZ:
3944 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003945 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003946 if (status < 0)
3947 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003948 /* cochannel protection for PAL 7 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003949 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003950 if (status < 0)
3951 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003952 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003953 if (status < 0)
3954 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003955 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003956 if (status < 0)
3957 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003958 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003959 if (status < 0)
3960 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003961 break;
3962 case BANDWIDTH_6_MHZ:
3963 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003964 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003965 if (status < 0)
3966 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003967 /* cochannel protection for NTSC 6 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003968 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003969 if (status < 0)
3970 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003971 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003972 if (status < 0)
3973 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003974 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003975 if (status < 0)
3976 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003977 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003978 if (status < 0)
3979 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003980 break;
Mauro Carvalho Chehabe16cede2011-07-03 18:18:14 -03003981 default:
3982 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003983 }
3984
Oliver Endrissebc7de22011-07-03 13:49:44 -03003985 if (iqmRcRateOfs == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003986 /* Now compute IQM_RC_RATE_OFS
3987 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3988 =>
3989 ((SysFreq / BandWidth) * (2^21)) - (2^23)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003990 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003991 /* (SysFreq / BandWidth) * (2^28) */
3992 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
3993 => assert(MAX(sysClk) < 16*MIN(bandwidth))
3994 => assert(109714272 > 48000000) = true so Frac 28 can be used */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003995 iqmRcRateOfs = Frac28a((u32)
3996 ((state->m_sysClockFreq *
3997 1000) / 3), bandwidth);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003998 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
3999 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004000 iqmRcRateOfs += 0x80L;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004001 iqmRcRateOfs = iqmRcRateOfs >> 7;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004002 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004003 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004004 }
4005
Oliver Endrissebc7de22011-07-03 13:49:44 -03004006 iqmRcRateOfs &=
4007 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4008 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004009 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004010 if (status < 0)
4011 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004012
4013 /* Bandwidth setting done */
4014
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004015#if 0
4016 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4017 if (status < 0)
4018 break;
4019#endif
4020 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4021 if (status < 0)
4022 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004023
4024 /*== Start SC, write channel settings to SC ===============================*/
4025
4026 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004027 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004028 if (status < 0)
4029 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004030
4031 /* Enable SC after setting all other parameters */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004032 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004033 if (status < 0)
4034 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004035 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004036 if (status < 0)
4037 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004038
4039
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004040 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4041 if (status < 0)
4042 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004043
4044 /* Write SC parameter registers, set all AUTO flags in operation mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004045 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4046 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4047 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4048 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4049 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4050 status =
4051 DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4052 0, transmissionParams, param1, 0, 0, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004053 if (!state->m_DRXK_A3_ROM_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004054 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4055 if (status < 0)
4056 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004057
Oliver Endrissebc7de22011-07-03 13:49:44 -03004058 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004059
4060 return status;
4061}
4062
4063
4064/*============================================================================*/
4065
4066/**
4067* \brief Retreive lock status .
4068* \param demod Pointer to demodulator instance.
4069* \param lockStat Pointer to lock status structure.
4070* \return DRXStatus_t.
4071*
4072*/
4073static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4074{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004075 int status;
4076 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4077 OFDM_SC_RA_RAM_LOCK_FEC__M);
4078 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4079 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004080
Oliver Endrissebc7de22011-07-03 13:49:44 -03004081 u16 ScRaRamLock = 0;
4082 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004083
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004084 dprintk(1, "\n");
4085
Oliver Endrissebc7de22011-07-03 13:49:44 -03004086 /* driver 0.9.0 */
4087 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004088 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004089 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP) {
4090 /* SC not active; return DRX_NOT_LOCKED */
4091 *pLockStatus = NOT_LOCKED;
4092 return status;
4093 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004094
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004095 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004096
Oliver Endrissebc7de22011-07-03 13:49:44 -03004097 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4098 *pLockStatus = MPEG_LOCK;
4099 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4100 *pLockStatus = FEC_LOCK;
4101 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4102 *pLockStatus = DEMOD_LOCK;
4103 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4104 *pLockStatus = NEVER_LOCK;
4105 else
4106 *pLockStatus = NOT_LOCKED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004107
Oliver Endrissebc7de22011-07-03 13:49:44 -03004108 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004109}
4110
Oliver Endrissebc7de22011-07-03 13:49:44 -03004111static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004112{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004113 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
4114 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004115
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004116 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004117 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004118 status = CtrlPowerMode(state, &powerMode);
4119 if (status < 0)
4120 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004121
Oliver Endrissebc7de22011-07-03 13:49:44 -03004122 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004123
Oliver Endrissebc7de22011-07-03 13:49:44 -03004124 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004125}
4126
4127
Oliver Endrissebc7de22011-07-03 13:49:44 -03004128/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004129static int PowerDownQAM(struct drxk_state *state)
4130{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004131 u16 data = 0;
4132 u16 cmdResult;
4133 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004134
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004135 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004136 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004137 status = read16(state, SCU_COMM_EXEC__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004138 if (status < 0)
4139 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004140 if (data == SCU_COMM_EXEC_ACTIVE) {
4141 /*
4142 STOP demodulator
4143 QAM and HW blocks
4144 */
4145 /* stop all comstate->m_exec */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004146 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004147 if (status < 0)
4148 break;
4149 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
4150 if (status < 0)
4151 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004152 }
4153 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004154 status = SetIqmAf(state, false);
4155 if (status < 0)
4156 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004157 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004158
Oliver Endrissebc7de22011-07-03 13:49:44 -03004159 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004160}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004161
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004162/*============================================================================*/
4163
4164/**
4165* \brief Setup of the QAM Measurement intervals for signal quality
4166* \param demod instance of demod.
4167* \param constellation current constellation.
4168* \return DRXStatus_t.
4169*
4170* NOTE:
4171* Take into account that for certain settings the errorcounters can overflow.
4172* The implementation does not check this.
4173*
4174*/
4175static int SetQAMMeasurement(struct drxk_state *state,
4176 enum EDrxkConstellation constellation,
4177 u32 symbolRate)
4178{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004179 u32 fecBitsDesired = 0; /* BER accounting period */
4180 u32 fecRsPeriodTotal = 0; /* Total period */
4181 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4182 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004183 int status = 0;
4184
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004185 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004186
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004187 fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004188 do {
4189
4190 /* fecBitsDesired = symbolRate [kHz] *
4191 FrameLenght [ms] *
4192 (constellation + 1) *
4193 SyncLoss (== 1) *
4194 ViterbiLoss (==1)
Oliver Endrissebc7de22011-07-03 13:49:44 -03004195 */
4196 switch (constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004197 case DRX_CONSTELLATION_QAM16:
4198 fecBitsDesired = 4 * symbolRate;
4199 break;
4200 case DRX_CONSTELLATION_QAM32:
4201 fecBitsDesired = 5 * symbolRate;
4202 break;
4203 case DRX_CONSTELLATION_QAM64:
4204 fecBitsDesired = 6 * symbolRate;
4205 break;
4206 case DRX_CONSTELLATION_QAM128:
4207 fecBitsDesired = 7 * symbolRate;
4208 break;
4209 case DRX_CONSTELLATION_QAM256:
4210 fecBitsDesired = 8 * symbolRate;
4211 break;
4212 default:
4213 status = -EINVAL;
4214 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004215 status = status;
4216 if (status < 0)
4217 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004218
Oliver Endrissebc7de22011-07-03 13:49:44 -03004219 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4220 fecBitsDesired *= 500; /* meas. period [ms] */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004221
4222 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4223 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004224 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004225
4226 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4227 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4228 if (fecRsPrescale == 0) {
4229 /* Divide by zero (though impossible) */
4230 status = -1;
4231 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004232 status = status;
4233 if (status < 0)
4234 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004235 fecRsPeriod =
4236 ((u16) fecRsPeriodTotal +
4237 (fecRsPrescale >> 1)) / fecRsPrescale;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004238
4239 /* write corresponding registers */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004240 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004241 if (status < 0)
4242 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004243 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004244 if (status < 0)
4245 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004246 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004247 if (status < 0)
4248 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004249
4250 } while (0);
4251
Oliver Endrissebc7de22011-07-03 13:49:44 -03004252 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03004253 printk(KERN_ERR "drxk: %s: status - %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004254
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004255 return status;
4256}
4257
Oliver Endrissebc7de22011-07-03 13:49:44 -03004258static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004259{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004260 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004261
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004262 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004263 do {
4264 /* QAM Equalizer Setup */
4265 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004266 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004267 if (status < 0)
4268 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004269 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004270 if (status < 0)
4271 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004272 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004273 if (status < 0)
4274 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004275 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004276 if (status < 0)
4277 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004278 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004279 if (status < 0)
4280 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004281 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004282 if (status < 0)
4283 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004284 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004285 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004286 if (status < 0)
4287 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004288 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004289 if (status < 0)
4290 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004291 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004292 if (status < 0)
4293 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004294 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004295 if (status < 0)
4296 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004297 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004298 if (status < 0)
4299 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004300 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004301 if (status < 0)
4302 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004303
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004304 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004305 if (status < 0)
4306 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004307 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004308 if (status < 0)
4309 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004310 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004311 if (status < 0)
4312 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004313
Oliver Endrissebc7de22011-07-03 13:49:44 -03004314 /* QAM Slicer Settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004315 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
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 Loop Controller Coeficients */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004320 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004321 if (status < 0)
4322 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004323 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004324 if (status < 0)
4325 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004326 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004327 if (status < 0)
4328 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004329 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004330 if (status < 0)
4331 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004332 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004333 if (status < 0)
4334 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004335 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004336 if (status < 0)
4337 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004338 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004339 if (status < 0)
4340 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004341 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004342 if (status < 0)
4343 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004344
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004345 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004346 if (status < 0)
4347 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004348 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004349 if (status < 0)
4350 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004351 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004352 if (status < 0)
4353 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004354 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004355 if (status < 0)
4356 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004357 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004358 if (status < 0)
4359 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004360 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004361 if (status < 0)
4362 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004363 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004364 if (status < 0)
4365 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004366 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004367 if (status < 0)
4368 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004369 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004370 if (status < 0)
4371 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004372 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004373 if (status < 0)
4374 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004375 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004376 if (status < 0)
4377 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004378 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004379 if (status < 0)
4380 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004381
4382
Oliver Endrissebc7de22011-07-03 13:49:44 -03004383 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004384
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004385 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004386 if (status < 0)
4387 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004388 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004389 if (status < 0)
4390 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004391 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004392 if (status < 0)
4393 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004394 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004395 if (status < 0)
4396 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004397 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004398 if (status < 0)
4399 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004400 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004401 if (status < 0)
4402 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004403
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004404 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004405 if (status < 0)
4406 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004407 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004408 if (status < 0)
4409 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004410 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004411 if (status < 0)
4412 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004413
4414
Oliver Endrissebc7de22011-07-03 13:49:44 -03004415 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004416
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004417 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004418 if (status < 0)
4419 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004420 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004421 if (status < 0)
4422 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004423 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004424 if (status < 0)
4425 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004426 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004427 if (status < 0)
4428 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004429 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004430 if (status < 0)
4431 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004432 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004433 if (status < 0)
4434 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004435 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004436 if (status < 0)
4437 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004438 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004439
Oliver Endrissebc7de22011-07-03 13:49:44 -03004440 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004441}
4442
4443/*============================================================================*/
4444
4445/**
4446* \brief QAM32 specific setup
4447* \param demod instance of demod.
4448* \return DRXStatus_t.
4449*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004450static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004451{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004452 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004453
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004454 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004455 do {
4456 /* QAM Equalizer Setup */
4457 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004458 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004459 if (status < 0)
4460 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004461 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004462 if (status < 0)
4463 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004464 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004465 if (status < 0)
4466 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004467 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004468 if (status < 0)
4469 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004470 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004471 if (status < 0)
4472 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004473 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004474 if (status < 0)
4475 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004476
Oliver Endrissebc7de22011-07-03 13:49:44 -03004477 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004478 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004479 if (status < 0)
4480 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004481 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004482 if (status < 0)
4483 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004484 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004485 if (status < 0)
4486 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004487 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004488 if (status < 0)
4489 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004490 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004491 if (status < 0)
4492 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004493 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004494 if (status < 0)
4495 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004496
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004497 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004498 if (status < 0)
4499 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004500 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004501 if (status < 0)
4502 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004503 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004504 if (status < 0)
4505 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004506
Oliver Endrissebc7de22011-07-03 13:49:44 -03004507 /* QAM Slicer Settings */
4508
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004509 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004510 if (status < 0)
4511 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004512
4513
Oliver Endrissebc7de22011-07-03 13:49:44 -03004514 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004515
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004516 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004517 if (status < 0)
4518 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004519 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004520 if (status < 0)
4521 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004522 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004523 if (status < 0)
4524 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004525 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004526 if (status < 0)
4527 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004528 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004529 if (status < 0)
4530 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004531 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004532 if (status < 0)
4533 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004534 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004535 if (status < 0)
4536 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004537 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004538 if (status < 0)
4539 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004540
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004541 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004542 if (status < 0)
4543 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004544 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004545 if (status < 0)
4546 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004547 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004548 if (status < 0)
4549 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004550 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004551 if (status < 0)
4552 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004553 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004554 if (status < 0)
4555 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004556 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004557 if (status < 0)
4558 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004559 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004560 if (status < 0)
4561 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004562 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004563 if (status < 0)
4564 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004565 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004566 if (status < 0)
4567 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004568 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004569 if (status < 0)
4570 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004571 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004572 if (status < 0)
4573 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004574 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004575 if (status < 0)
4576 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004577
4578
Oliver Endrissebc7de22011-07-03 13:49:44 -03004579 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004580
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004581 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004582 if (status < 0)
4583 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004584 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004585 if (status < 0)
4586 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004587 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004588 if (status < 0)
4589 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004590 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004591 if (status < 0)
4592 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004593 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004594 if (status < 0)
4595 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004596 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004597 if (status < 0)
4598 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004599
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004600 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004601 if (status < 0)
4602 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004603 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004604 if (status < 0)
4605 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004606 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004607 if (status < 0)
4608 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004609
4610
Oliver Endrissebc7de22011-07-03 13:49:44 -03004611 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004612
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004613 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004614 if (status < 0)
4615 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004616 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004617 if (status < 0)
4618 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004619 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004620 if (status < 0)
4621 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004622 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004623 if (status < 0)
4624 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004625 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004626 if (status < 0)
4627 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004628 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004629 if (status < 0)
4630 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004631 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004632 if (status < 0)
4633 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004634 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004635
Oliver Endrissebc7de22011-07-03 13:49:44 -03004636 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004637}
4638
4639/*============================================================================*/
4640
4641/**
4642* \brief QAM64 specific setup
4643* \param demod instance of demod.
4644* \return DRXStatus_t.
4645*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004646static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004647{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004648 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004649
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004650 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004651 do {
4652 /* QAM Equalizer Setup */
4653 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004654 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004655 if (status < 0)
4656 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004657 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004658 if (status < 0)
4659 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004660 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004661 if (status < 0)
4662 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004663 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004664 if (status < 0)
4665 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004666 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004667 if (status < 0)
4668 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004669 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004670 if (status < 0)
4671 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004672
Oliver Endrissebc7de22011-07-03 13:49:44 -03004673 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004674 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004675 if (status < 0)
4676 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004677 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004678 if (status < 0)
4679 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004680 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004681 if (status < 0)
4682 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004683 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004684 if (status < 0)
4685 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004686 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004687 if (status < 0)
4688 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004689 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004690 if (status < 0)
4691 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004692
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004693 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004694 if (status < 0)
4695 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004696 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004697 if (status < 0)
4698 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004699 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004700 if (status < 0)
4701 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004702
4703 /* QAM Slicer Settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004704 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004705 if (status < 0)
4706 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004707
4708
Oliver Endrissebc7de22011-07-03 13:49:44 -03004709 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004710
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004711 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004712 if (status < 0)
4713 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004714 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004715 if (status < 0)
4716 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004717 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004718 if (status < 0)
4719 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004720 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004721 if (status < 0)
4722 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004723 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004724 if (status < 0)
4725 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004726 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004727 if (status < 0)
4728 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004729 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004730 if (status < 0)
4731 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004732 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004733 if (status < 0)
4734 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004735
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004736 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004737 if (status < 0)
4738 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004739 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004740 if (status < 0)
4741 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004742 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004743 if (status < 0)
4744 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004745 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004746 if (status < 0)
4747 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004748 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004749 if (status < 0)
4750 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004751 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004752 if (status < 0)
4753 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004754 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004755 if (status < 0)
4756 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004757 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004758 if (status < 0)
4759 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004760 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004761 if (status < 0)
4762 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004763 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004764 if (status < 0)
4765 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004766 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004767 if (status < 0)
4768 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004769 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004770 if (status < 0)
4771 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004772
4773
Oliver Endrissebc7de22011-07-03 13:49:44 -03004774 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004775
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004776 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004777 if (status < 0)
4778 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004779 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004780 if (status < 0)
4781 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004782 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004783 if (status < 0)
4784 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004785 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004786 if (status < 0)
4787 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004788 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004789 if (status < 0)
4790 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004791 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004792 if (status < 0)
4793 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004794
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004795 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004796 if (status < 0)
4797 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004798 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004799 if (status < 0)
4800 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004801 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004802 if (status < 0)
4803 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004804
4805
Oliver Endrissebc7de22011-07-03 13:49:44 -03004806 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004807
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004808 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004809 if (status < 0)
4810 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004811 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004812 if (status < 0)
4813 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004814 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004815 if (status < 0)
4816 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004817 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004818 if (status < 0)
4819 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004820 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004821 if (status < 0)
4822 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004823 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004824 if (status < 0)
4825 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004826 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004827 if (status < 0)
4828 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004829 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004830
Oliver Endrissebc7de22011-07-03 13:49:44 -03004831 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004832}
4833
4834/*============================================================================*/
4835
4836/**
4837* \brief QAM128 specific setup
4838* \param demod: instance of demod.
4839* \return DRXStatus_t.
4840*/
4841static int SetQAM128(struct drxk_state *state)
4842{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004843 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004844
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004845 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004846 do {
4847 /* QAM Equalizer Setup */
4848 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004849 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004850 if (status < 0)
4851 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004852 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004853 if (status < 0)
4854 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004855 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004856 if (status < 0)
4857 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004858 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004859 if (status < 0)
4860 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004861 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004862 if (status < 0)
4863 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004864 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004865 if (status < 0)
4866 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004867
Oliver Endrissebc7de22011-07-03 13:49:44 -03004868 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004869 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004870 if (status < 0)
4871 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004872 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004873 if (status < 0)
4874 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004875 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004876 if (status < 0)
4877 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004878 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004879 if (status < 0)
4880 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004881 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004882 if (status < 0)
4883 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004884 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004885 if (status < 0)
4886 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004887
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004888 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004889 if (status < 0)
4890 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004891 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004892 if (status < 0)
4893 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004894 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004895 if (status < 0)
4896 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004897
4898
Oliver Endrissebc7de22011-07-03 13:49:44 -03004899 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004900
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004901 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004902 if (status < 0)
4903 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004904
4905
Oliver Endrissebc7de22011-07-03 13:49:44 -03004906 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004907
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004908 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004909 if (status < 0)
4910 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004911 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004912 if (status < 0)
4913 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004914 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004915 if (status < 0)
4916 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004917 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004918 if (status < 0)
4919 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004920 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004921 if (status < 0)
4922 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004923 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004924 if (status < 0)
4925 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004926 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004927 if (status < 0)
4928 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004929 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004930 if (status < 0)
4931 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004932
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004933 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004934 if (status < 0)
4935 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004936 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004937 if (status < 0)
4938 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004939 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004940 if (status < 0)
4941 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004942 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004943 if (status < 0)
4944 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004945 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004946 if (status < 0)
4947 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004948 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004949 if (status < 0)
4950 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004951 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004952 if (status < 0)
4953 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004954 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004955 if (status < 0)
4956 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004957 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004958 if (status < 0)
4959 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004960 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004961 if (status < 0)
4962 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004963 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004964 if (status < 0)
4965 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004966 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004967 if (status < 0)
4968 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004969
4970
Oliver Endrissebc7de22011-07-03 13:49:44 -03004971 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004972
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004973 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004974 if (status < 0)
4975 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004976 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004977 if (status < 0)
4978 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004979 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004980 if (status < 0)
4981 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004982 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004983 if (status < 0)
4984 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004985 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004986 if (status < 0)
4987 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004988 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004989 if (status < 0)
4990 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004991
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004992 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004993 if (status < 0)
4994 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004995 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004996 if (status < 0)
4997 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004998
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004999 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005000 if (status < 0)
5001 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005002
Oliver Endrissebc7de22011-07-03 13:49:44 -03005003 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005004
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005005 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005006 if (status < 0)
5007 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005008 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005009 if (status < 0)
5010 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005011 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005012 if (status < 0)
5013 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005014 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005015 if (status < 0)
5016 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005017 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005018 if (status < 0)
5019 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005020 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005021 if (status < 0)
5022 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005023 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005024 if (status < 0)
5025 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005026 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005027
Oliver Endrissebc7de22011-07-03 13:49:44 -03005028 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005029}
5030
5031/*============================================================================*/
5032
5033/**
5034* \brief QAM256 specific setup
5035* \param demod: instance of demod.
5036* \return DRXStatus_t.
5037*/
5038static int SetQAM256(struct drxk_state *state)
5039{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005040 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005041
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005042 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005043 do {
5044 /* QAM Equalizer Setup */
5045 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005046 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005047 if (status < 0)
5048 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005049 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005050 if (status < 0)
5051 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005052 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005053 if (status < 0)
5054 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005055 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005056 if (status < 0)
5057 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005058 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005059 if (status < 0)
5060 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005061 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005062 if (status < 0)
5063 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005064
Oliver Endrissebc7de22011-07-03 13:49:44 -03005065 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005066 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005067 if (status < 0)
5068 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005069 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005070 if (status < 0)
5071 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005072 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005073 if (status < 0)
5074 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005075 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005076 if (status < 0)
5077 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005078 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005079 if (status < 0)
5080 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005081 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005082 if (status < 0)
5083 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005084
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005085 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005086 if (status < 0)
5087 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005088 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005089 if (status < 0)
5090 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005091 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005092 if (status < 0)
5093 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005094
Oliver Endrissebc7de22011-07-03 13:49:44 -03005095 /* QAM Slicer Settings */
5096
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005097 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005098 if (status < 0)
5099 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005100
5101
Oliver Endrissebc7de22011-07-03 13:49:44 -03005102 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005103
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005104 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005105 if (status < 0)
5106 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005107 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005108 if (status < 0)
5109 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005110 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005111 if (status < 0)
5112 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005113 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005114 if (status < 0)
5115 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005116 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005117 if (status < 0)
5118 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005119 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005120 if (status < 0)
5121 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005122 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005123 if (status < 0)
5124 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005125 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005126 if (status < 0)
5127 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005128
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005129 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005130 if (status < 0)
5131 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005132 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005133 if (status < 0)
5134 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005135 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005136 if (status < 0)
5137 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005138 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005139 if (status < 0)
5140 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005141 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005142 if (status < 0)
5143 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005144 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005145 if (status < 0)
5146 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005147 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005148 if (status < 0)
5149 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005150 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005151 if (status < 0)
5152 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005153 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005154 if (status < 0)
5155 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005156 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005157 if (status < 0)
5158 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005159 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005160 if (status < 0)
5161 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005162 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005163 if (status < 0)
5164 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005165
5166
Oliver Endrissebc7de22011-07-03 13:49:44 -03005167 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005168
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005169 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005170 if (status < 0)
5171 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005172 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005173 if (status < 0)
5174 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005175 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005176 if (status < 0)
5177 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005178 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005179 if (status < 0)
5180 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005181 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005182 if (status < 0)
5183 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005184 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005185 if (status < 0)
5186 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005187
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005188 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005189 if (status < 0)
5190 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005191 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005192 if (status < 0)
5193 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005194 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005195 if (status < 0)
5196 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005197
5198
Oliver Endrissebc7de22011-07-03 13:49:44 -03005199 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005200
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005201 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005202 if (status < 0)
5203 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005204 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005205 if (status < 0)
5206 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005207 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005208 if (status < 0)
5209 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005210 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005211 if (status < 0)
5212 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005213 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005214 if (status < 0)
5215 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005216 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005217 if (status < 0)
5218 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005219 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005220 if (status < 0)
5221 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005222 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005223
Oliver Endrissebc7de22011-07-03 13:49:44 -03005224 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005225}
5226
5227
5228/*============================================================================*/
5229/**
5230* \brief Reset QAM block.
5231* \param demod: instance of demod.
5232* \param channel: pointer to channel data.
5233* \return DRXStatus_t.
5234*/
5235static int QAMResetQAM(struct drxk_state *state)
5236{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005237 int status;
5238 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005239
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005240 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005241 do {
5242 /* Stop QAM comstate->m_exec */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005243 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005244 if (status < 0)
5245 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005246
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005247 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5248 if (status < 0)
5249 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005250 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005251
Oliver Endrissebc7de22011-07-03 13:49:44 -03005252 /* All done, all OK */
5253 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005254}
5255
5256/*============================================================================*/
5257
5258/**
5259* \brief Set QAM symbolrate.
5260* \param demod: instance of demod.
5261* \param channel: pointer to channel data.
5262* \return DRXStatus_t.
5263*/
5264static int QAMSetSymbolrate(struct drxk_state *state)
5265{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005266 u32 adcFrequency = 0;
5267 u32 symbFreq = 0;
5268 u32 iqmRcRate = 0;
5269 u16 ratesel = 0;
5270 u32 lcSymbRate = 0;
5271 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005272
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005273 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005274 do {
5275 /* Select & calculate correct IQM rate */
5276 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5277 ratesel = 0;
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005278 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005279 if (state->param.u.qam.symbol_rate <= 1188750)
5280 ratesel = 3;
5281 else if (state->param.u.qam.symbol_rate <= 2377500)
5282 ratesel = 2;
5283 else if (state->param.u.qam.symbol_rate <= 4755000)
5284 ratesel = 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005285 status = write16(state, IQM_FD_RATESEL__A, ratesel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005286 if (status < 0)
5287 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005288
Oliver Endrissebc7de22011-07-03 13:49:44 -03005289 /*
5290 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5291 */
5292 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5293 if (symbFreq == 0) {
5294 /* Divide by zero */
5295 return -1;
5296 }
5297 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5298 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5299 (1 << 23);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005300 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005301 if (status < 0)
5302 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005303 state->m_iqmRcRate = iqmRcRate;
5304 /*
5305 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5306 */
5307 symbFreq = state->param.u.qam.symbol_rate;
5308 if (adcFrequency == 0) {
5309 /* Divide by zero */
5310 return -1;
5311 }
5312 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5313 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5314 16);
5315 if (lcSymbRate > 511)
5316 lcSymbRate = 511;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005317 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005318 if (status < 0)
5319 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005320 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005321
Oliver Endrissebc7de22011-07-03 13:49:44 -03005322 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005323}
5324
5325/*============================================================================*/
5326
5327/**
5328* \brief Get QAM lock status.
5329* \param demod: instance of demod.
5330* \param channel: pointer to channel data.
5331* \return DRXStatus_t.
5332*/
5333
5334static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5335{
5336 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005337 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005338
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005339 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005340 status =
5341 scu_command(state,
5342 SCU_RAM_COMMAND_STANDARD_QAM |
5343 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5344 Result);
5345 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005346 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005347
5348 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005349 /* 0x0000 NOT LOCKED */
5350 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005351 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005352 /* 0x4000 DEMOD LOCKED */
5353 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005354 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005355 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5356 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005357 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005358 /* 0xC000 NEVER LOCKED */
5359 /* (system will never be able to lock to the signal) */
5360 /* TODO: check this, intermediate & standard specific lock states are not
5361 taken into account here */
5362 *pLockStatus = NEVER_LOCK;
5363 }
5364 return status;
5365}
5366
5367#define QAM_MIRROR__M 0x03
5368#define QAM_MIRROR_NORMAL 0x00
5369#define QAM_MIRRORED 0x01
5370#define QAM_MIRROR_AUTO_ON 0x02
5371#define QAM_LOCKRANGE__M 0x10
5372#define QAM_LOCKRANGE_NORMAL 0x10
5373
Oliver Endrissebc7de22011-07-03 13:49:44 -03005374static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5375 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005376{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005377 int status = 0;
5378 u8 parameterLen;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005379 u16 setEnvParameters[5];
5380 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5381 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005382
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005383 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005384 do {
5385 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005386 STEP 1: reset demodulator
5387 resets FEC DI and FEC RS
5388 resets QAM block
5389 resets SCU variables
5390 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005391 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005392 if (status < 0)
5393 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005394 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005395 if (status < 0)
5396 break;
5397 status = QAMResetQAM(state);
5398 if (status < 0)
5399 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005400
5401 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005402 STEP 2: configure demodulator
5403 -set env
5404 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5405 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005406 status = QAMSetSymbolrate(state);
5407 if (status < 0)
5408 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005409
5410 /* Env parameters */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005411 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005412 if (state->m_OperationMode == OM_QAM_ITU_C)
Oliver Endrissebc7de22011-07-03 13:49:44 -03005413 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005414 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005415 /* check for LOCKRANGE Extented */
5416 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005417 parameterLen = 4;
5418
5419 /* Set params */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005420 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005421 case QAM_256:
5422 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5423 break;
5424 case QAM_AUTO:
5425 case QAM_64:
5426 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5427 break;
5428 case QAM_16:
5429 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5430 break;
5431 case QAM_32:
5432 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5433 break;
5434 case QAM_128:
5435 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5436 break;
5437 default:
5438 status = -EINVAL;
5439 break;
5440 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005441 status = status;
5442 if (status < 0)
5443 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005444 setParamParameters[0] = state->m_Constellation; /* constellation */
5445 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005446
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005447 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5448 if (status < 0)
5449 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005450
5451
5452 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5453 setup constellation independent registers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005454#if 0
5455 status = SetFrequency (channel, tunerFreqOffset));
5456 if (status < 0)
5457 break;
5458#endif
5459 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5460 if (status < 0)
5461 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005462
5463 /* Setup BER measurement */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005464 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5465 if (status < 0)
5466 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005467
5468 /* Reset default values */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005469 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005470 if (status < 0)
5471 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005472 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005473 if (status < 0)
5474 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005475
Oliver Endrissebc7de22011-07-03 13:49:44 -03005476 /* Reset default LC values */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005477 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005478 if (status < 0)
5479 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005480 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005481 if (status < 0)
5482 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005483 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005484 if (status < 0)
5485 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005486 status = write16(state, QAM_LC_MODE__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005487 if (status < 0)
5488 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005489
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005490 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005491 if (status < 0)
5492 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005493 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005494 if (status < 0)
5495 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005496 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005497 if (status < 0)
5498 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005499 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005500 if (status < 0)
5501 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005502 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005503 if (status < 0)
5504 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005505 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005506 if (status < 0)
5507 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005508 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005509 if (status < 0)
5510 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005511 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005512 if (status < 0)
5513 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005514 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005515 if (status < 0)
5516 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005517 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005518 if (status < 0)
5519 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005520 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005521 if (status < 0)
5522 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005523 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005524 if (status < 0)
5525 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005526 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005527 if (status < 0)
5528 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005529 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005530 if (status < 0)
5531 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005532 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005533 if (status < 0)
5534 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005535
Oliver Endrissebc7de22011-07-03 13:49:44 -03005536 /* Mirroring, QAM-block starting point not inverted */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005537 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
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 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005542 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
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 /* STEP 4: constellation specific setup */
5547 switch (state->param.u.qam.modulation) {
5548 case QAM_16:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005549 status = SetQAM16(state);
5550 if (status < 0)
5551 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005552 break;
5553 case QAM_32:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005554 status = SetQAM32(state);
5555 if (status < 0)
5556 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005557 break;
5558 case QAM_AUTO:
5559 case QAM_64:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005560 status = SetQAM64(state);
5561 if (status < 0)
5562 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005563 break;
5564 case QAM_128:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005565 status = SetQAM128(state);
5566 if (status < 0)
5567 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005568 break;
5569 case QAM_256:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005570 status = SetQAM256(state);
5571 if (status < 0)
5572 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005573 break;
5574 default:
5575 return -1;
5576 break;
5577 } /* switch */
5578 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005579 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005580 if (status < 0)
5581 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005582
5583
Oliver Endrissebc7de22011-07-03 13:49:44 -03005584 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5585 /* extAttr->currentChannel.constellation = channel->constellation; */
5586 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005587 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5588 if (status < 0)
5589 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005590
Oliver Endrissebc7de22011-07-03 13:49:44 -03005591 /* Start processes */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005592 status = MPEGTSStart(state);
5593 if (status < 0)
5594 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005595 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005596 if (status < 0)
5597 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005598 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005599 if (status < 0)
5600 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005601 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005602 if (status < 0)
5603 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005604
Oliver Endrissebc7de22011-07-03 13:49:44 -03005605 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005606 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5607 if (status < 0)
5608 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005609
Oliver Endrissebc7de22011-07-03 13:49:44 -03005610 /* update global DRXK data container */
5611 /*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005612
Oliver Endrissebc7de22011-07-03 13:49:44 -03005613 /* All done, all OK */
5614 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005615
Oliver Endrissebc7de22011-07-03 13:49:44 -03005616 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005617 printk(KERN_ERR "drxk: %s %d\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005618
5619 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005620}
5621
Oliver Endrissebc7de22011-07-03 13:49:44 -03005622static int SetQAMStandard(struct drxk_state *state,
5623 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005624{
5625#ifdef DRXK_QAM_TAPS
5626#define DRXK_QAMA_TAPS_SELECT
5627#include "drxk_filters.h"
5628#undef DRXK_QAMA_TAPS_SELECT
5629#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03005630 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005631#endif
5632
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005633 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005634 do {
5635 /* added antenna switch */
5636 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005637
Oliver Endrissebc7de22011-07-03 13:49:44 -03005638 /* Ensure correct power-up mode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005639 status = PowerUpQAM(state);
5640 if (status < 0)
5641 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005642 /* Reset QAM block */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005643 status = QAMResetQAM(state);
5644 if (status < 0)
5645 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005646
Oliver Endrissebc7de22011-07-03 13:49:44 -03005647 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005648
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005649 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005650 if (status < 0)
5651 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005652 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005653 if (status < 0)
5654 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005655
Oliver Endrissebc7de22011-07-03 13:49:44 -03005656 /* Upload IQM Channel Filter settings by
5657 boot loader from ROM table */
5658 switch (oMode) {
5659 case OM_QAM_ITU_A:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005660 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5661 if (status < 0)
5662 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005663 break;
5664 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005665 status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5666 if (status < 0)
5667 break;
5668 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5669 if (status < 0)
5670 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005671 break;
5672 default:
5673 status = -EINVAL;
5674 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005675 status = status;
5676 if (status < 0)
5677 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005678
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005679 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005680 if (status < 0)
5681 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005682 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005683 if (status < 0)
5684 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005685 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005686 if (status < 0)
5687 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005688
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005689 status = write16(state, IQM_RC_STRETCH__A, 21);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005690 if (status < 0)
5691 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005692 status = write16(state, IQM_AF_CLP_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005693 if (status < 0)
5694 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005695 status = write16(state, IQM_AF_CLP_TH__A, 448);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005696 if (status < 0)
5697 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005698 status = write16(state, IQM_AF_SNS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005699 if (status < 0)
5700 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005701 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005702 if (status < 0)
5703 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005704
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005705 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005706 if (status < 0)
5707 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005708 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005709 if (status < 0)
5710 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005711 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005712 if (status < 0)
5713 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005714 status = write16(state, IQM_AF_UPD_SEL__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005715 if (status < 0)
5716 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005717
Oliver Endrissebc7de22011-07-03 13:49:44 -03005718 /* IQM Impulse Noise Processing Unit */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005719 status = write16(state, IQM_CF_CLP_VAL__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005720 if (status < 0)
5721 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005722 status = write16(state, IQM_CF_DATATH__A, 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005723 if (status < 0)
5724 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005725 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005726 if (status < 0)
5727 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005728 status = write16(state, IQM_CF_DET_LCT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005729 if (status < 0)
5730 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005731 status = write16(state, IQM_CF_WND_LEN__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005732 if (status < 0)
5733 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005734 status = write16(state, IQM_CF_PKDTH__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005735 if (status < 0)
5736 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005737 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005738 if (status < 0)
5739 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005740
Oliver Endrissebc7de22011-07-03 13:49:44 -03005741 /* turn on IQMAF. Must be done before setAgc**() */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005742 status = SetIqmAf(state, true);
5743 if (status < 0)
5744 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005745 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005746 if (status < 0)
5747 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005748
Oliver Endrissebc7de22011-07-03 13:49:44 -03005749 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005750 status = ADCSynchronization(state);
5751 if (status < 0)
5752 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005753
Oliver Endrissebc7de22011-07-03 13:49:44 -03005754 /* Set the FSM step period */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005755 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005756 if (status < 0)
5757 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005758
Oliver Endrissebc7de22011-07-03 13:49:44 -03005759 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005760 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
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 /* No more resets of the IQM, current standard correctly set =>
5765 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005766
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005767 status = InitAGC(state, true);
5768 if (status < 0)
5769 break;
5770 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5771 if (status < 0)
5772 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005773
Oliver Endrissebc7de22011-07-03 13:49:44 -03005774 /* Configure AGC's */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005775 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5776 if (status < 0)
5777 break;
5778 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5779 if (status < 0)
5780 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005781
Oliver Endrissebc7de22011-07-03 13:49:44 -03005782 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005783 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005784 if (status < 0)
5785 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005786 } while (0);
5787 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005788}
5789
5790static int WriteGPIO(struct drxk_state *state)
5791{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005792 int status;
5793 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005794
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005795 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005796 do {
5797 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005798 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005799 if (status < 0)
5800 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005801
Oliver Endrissebc7de22011-07-03 13:49:44 -03005802 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005803 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
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 if (state->m_hasSAWSW) {
5808 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005809 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005810 if (status < 0)
5811 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005812
Oliver Endrissebc7de22011-07-03 13:49:44 -03005813 /* use corresponding bit in io data output registar */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005814 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005815 if (status < 0)
5816 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005817 if (state->m_GPIO == 0)
5818 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5819 else
5820 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5821 /* write back to io data output register */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005822 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005823 if (status < 0)
5824 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005825
Oliver Endrissebc7de22011-07-03 13:49:44 -03005826 }
5827 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005828 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005829 if (status < 0)
5830 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005831 } while (0);
5832 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005833}
5834
5835static int SwitchAntennaToQAM(struct drxk_state *state)
5836{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005837 int status = -1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005838
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005839 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005840 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5841 if (state->m_GPIO != state->m_AntennaDVBC) {
5842 state->m_GPIO = state->m_AntennaDVBC;
5843 status = WriteGPIO(state);
5844 }
5845 }
5846 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005847}
5848
5849static int SwitchAntennaToDVBT(struct drxk_state *state)
5850{
5851 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005852
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005853 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005854 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5855 if (state->m_GPIO != state->m_AntennaDVBT) {
5856 state->m_GPIO = state->m_AntennaDVBT;
5857 status = WriteGPIO(state);
5858 }
5859 }
5860 return status;
5861}
5862
5863
5864static int PowerDownDevice(struct drxk_state *state)
5865{
5866 /* Power down to requested mode */
5867 /* Backup some register settings */
5868 /* Set pins with possible pull-ups connected to them in input mode */
5869 /* Analog power down */
5870 /* ADC power down */
5871 /* Power down device */
5872 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005873
5874 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005875 do {
5876 if (state->m_bPDownOpenBridge) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03005877 /* Open I2C bridge before power down of DRXK */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005878 status = ConfigureI2CBridge(state, true);
5879 if (status < 0)
5880 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005881 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005882 /* driver 0.9.0 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005883 status = DVBTEnableOFDMTokenRing(state, false);
5884 if (status < 0)
5885 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005886
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005887 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005888 if (status < 0)
5889 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005890 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005891 if (status < 0)
5892 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005893 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005894 status = HI_CfgCommand(state);
5895 if (status < 0)
5896 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005897 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005898
Oliver Endrissebc7de22011-07-03 13:49:44 -03005899 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005900 return -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005901
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005902 return 0;
5903}
5904
5905static int load_microcode(struct drxk_state *state, char *mc_name)
5906{
5907 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005908 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005909
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005910 dprintk(1, "\n");
5911
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005912 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5913 if (err < 0) {
5914 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005915 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005916 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005917 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005918 return err;
5919 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005920 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005921 release_firmware(fw);
5922 return err;
5923}
5924
5925static int init_drxk(struct drxk_state *state)
5926{
5927 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005928 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005929 u16 driverVersion;
5930
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005931 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005932 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
5933 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005934 status = PowerUpDevice(state);
5935 if (status < 0)
5936 break;
5937 status = DRXX_Open(state);
5938 if (status < 0)
5939 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005940 /* Soft reset of OFDM-, sys- and osc-clockdomain */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005941 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 -03005942 if (status < 0)
5943 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005944 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005945 if (status < 0)
5946 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005947 /* TODO is this needed, if yes how much delay in worst case scenario */
5948 msleep(1);
5949 state->m_DRXK_A3_PATCH_CODE = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005950 status = GetDeviceCapabilities(state);
5951 if (status < 0)
5952 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005953
5954 /* Bridge delay, uses oscilator clock */
5955 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5956 /* SDA brdige delay */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005957 state->m_HICfgBridgeDelay =
5958 (u16) ((state->m_oscClockFreq / 1000) *
5959 HI_I2C_BRIDGE_DELAY) / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005960 /* Clipping */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005961 if (state->m_HICfgBridgeDelay >
5962 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
5963 state->m_HICfgBridgeDelay =
5964 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005965 }
5966 /* SCL bridge delay, same as SDA for now */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005967 state->m_HICfgBridgeDelay +=
5968 state->m_HICfgBridgeDelay <<
5969 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005970
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005971 status = InitHI(state);
5972 if (status < 0)
5973 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005974 /* disable various processes */
5975#if NOA1ROM
Oliver Endrissebc7de22011-07-03 13:49:44 -03005976 if (!(state->m_DRXK_A1_ROM_CODE)
5977 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005978#endif
5979 {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005980 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005981 if (status < 0)
5982 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005983 }
5984
5985 /* disable MPEG port */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005986 status = MPEGTSDisable(state);
5987 if (status < 0)
5988 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005989
5990 /* Stop AUD and SCU */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005991 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005992 if (status < 0)
5993 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005994 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005995 if (status < 0)
5996 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005997
5998 /* enable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005999 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 -03006000 if (status < 0)
6001 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006002
6003 /* include boot loader section */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006004 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006005 if (status < 0)
6006 break;
6007 status = BLChainCmd(state, 0, 6, 100);
6008 if (status < 0)
6009 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006010
6011#if 0
6012 if (state->m_DRXK_A3_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006013 status = DownloadMicrocode(state, DRXK_A3_microcode, DRXK_A3_microcode_length);
6014 if (status < 0)
6015 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006016#else
6017 load_microcode(state, "drxk_a3.mc");
6018#endif
6019#if NOA1ROM
6020 if (state->m_DRXK_A2_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006021 status = DownloadMicrocode(state, DRXK_A2_microcode, DRXK_A2_microcode_length);
6022 if (status < 0)
6023 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006024#endif
6025 /* disable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006026 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 -03006027 if (status < 0)
6028 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006029
6030 /* Run SCU for a little while to initialize microcode version numbers */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006031 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006032 if (status < 0)
6033 break;
6034 status = DRXX_Open(state);
6035 if (status < 0)
6036 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006037 /* added for test */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006038 msleep(30);
6039
6040 powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006041 status = CtrlPowerMode(state, &powerMode);
6042 if (status < 0)
6043 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006044
6045 /* Stamp driver version number in SCU data RAM in BCD code
6046 Done to enable field application engineers to retreive drxdriver version
6047 via I2C from SCU RAM.
6048 Not using SCU command interface for SCU register access since no
6049 microcode may be present.
Oliver Endrissebc7de22011-07-03 13:49:44 -03006050 */
6051 driverVersion =
6052 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6053 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6054 ((DRXK_VERSION_MAJOR % 10) << 4) +
6055 (DRXK_VERSION_MINOR % 10);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006056 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006057 if (status < 0)
6058 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006059 driverVersion =
6060 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6061 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6062 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6063 (DRXK_VERSION_PATCH % 10);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006064 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006065 if (status < 0)
6066 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006067
Oliver Endrissebc7de22011-07-03 13:49:44 -03006068 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6069 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6070 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006071
6072 /* Dirty fix of default values for ROM/PATCH microcode
6073 Dirty because this fix makes it impossible to setup suitable values
6074 before calling DRX_Open. This solution requires changes to RF AGC speed
6075 to be done via the CTRL function after calling DRX_Open */
6076
Oliver Endrissebc7de22011-07-03 13:49:44 -03006077 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006078
6079 /* Reset driver debug flags to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006080 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006081 if (status < 0)
6082 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006083 /* driver 0.9.0 */
6084 /* Setup FEC OC:
6085 NOTE: No more full FEC resets allowed afterwards!! */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006086 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006087 if (status < 0)
6088 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006089 /* MPEGTS functions are still the same */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006090 status = MPEGTSDtoInit(state);
6091 if (status < 0)
6092 break;
6093 status = MPEGTSStop(state);
6094 if (status < 0)
6095 break;
6096 status = MPEGTSConfigurePolarity(state);
6097 if (status < 0)
6098 break;
6099 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6100 if (status < 0)
6101 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006102 /* added: configure GPIO */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006103 status = WriteGPIO(state);
6104 if (status < 0)
6105 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006106
Oliver Endrissebc7de22011-07-03 13:49:44 -03006107 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006108
6109 if (state->m_bPowerDown) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006110 status = PowerDownDevice(state);
6111 if (status < 0)
6112 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006113 state->m_DrxkState = DRXK_POWERED_DOWN;
6114 } else
6115 state->m_DrxkState = DRXK_STOPPED;
6116 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006117 }
6118
6119 return 0;
6120}
6121
Oliver Endrissebc7de22011-07-03 13:49:44 -03006122static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006123{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006124 struct drxk_state *state = fe->demodulator_priv;
6125
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006126 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006127 kfree(state);
6128}
6129
Oliver Endrissebc7de22011-07-03 13:49:44 -03006130static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006131{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006132 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006133
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006134 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006135 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006136 return -EBUSY;
6137 SetOperationMode(state, OM_QAM_ITU_A);
6138 return 0;
6139}
6140
Oliver Endrissebc7de22011-07-03 13:49:44 -03006141static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006142{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006143 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006144
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006145 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006146 ShutDown(state);
6147 mutex_unlock(&state->ctlock);
6148 return 0;
6149}
6150
Oliver Endrissebc7de22011-07-03 13:49:44 -03006151static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006152{
6153 struct drxk_state *state = fe->demodulator_priv;
6154
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006155 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006156 return ConfigureI2CBridge(state, enable ? true : false);
6157}
6158
Oliver Endrissebc7de22011-07-03 13:49:44 -03006159static int drxk_set_parameters(struct dvb_frontend *fe,
6160 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006161{
6162 struct drxk_state *state = fe->demodulator_priv;
6163 u32 IF;
6164
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006165 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006166 if (fe->ops.i2c_gate_ctrl)
6167 fe->ops.i2c_gate_ctrl(fe, 1);
6168 if (fe->ops.tuner_ops.set_params)
6169 fe->ops.tuner_ops.set_params(fe, p);
6170 if (fe->ops.i2c_gate_ctrl)
6171 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006172 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006173 fe->ops.tuner_ops.get_frequency(fe, &IF);
6174 Start(state, 0, IF);
6175
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006176 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006177
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006178 return 0;
6179}
6180
Oliver Endrissebc7de22011-07-03 13:49:44 -03006181static int drxk_c_get_frontend(struct dvb_frontend *fe,
6182 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006183{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006184 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006185 return 0;
6186}
6187
6188static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6189{
6190 struct drxk_state *state = fe->demodulator_priv;
6191 u32 stat;
6192
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006193 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006194 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006195 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006196 if (stat == MPEG_LOCK)
6197 *status |= 0x1f;
6198 if (stat == FEC_LOCK)
6199 *status |= 0x0f;
6200 if (stat == DEMOD_LOCK)
6201 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006202 return 0;
6203}
6204
6205static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6206{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006207 dprintk(1, "\n");
6208
Oliver Endrissebc7de22011-07-03 13:49:44 -03006209 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006210 return 0;
6211}
6212
Oliver Endrissebc7de22011-07-03 13:49:44 -03006213static int drxk_read_signal_strength(struct dvb_frontend *fe,
6214 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006215{
6216 struct drxk_state *state = fe->demodulator_priv;
6217 u32 val;
6218
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006219 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006220 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006221 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006222 return 0;
6223}
6224
6225static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6226{
6227 struct drxk_state *state = fe->demodulator_priv;
6228 s32 snr2;
6229
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006230 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006231 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006232 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006233 return 0;
6234}
6235
6236static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6237{
6238 struct drxk_state *state = fe->demodulator_priv;
6239 u16 err;
6240
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006241 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006242 DVBTQAMGetAccPktErr(state, &err);
6243 *ucblocks = (u32) err;
6244 return 0;
6245}
6246
Oliver Endrissebc7de22011-07-03 13:49:44 -03006247static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6248 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006249{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006250 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006251 sets->min_delay_ms = 3000;
6252 sets->max_drift = 0;
6253 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006254 return 0;
6255}
6256
Oliver Endrissebc7de22011-07-03 13:49:44 -03006257static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006258{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006259#if 0
6260 struct drxk_state *state = fe->demodulator_priv;
6261
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006262 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006263 kfree(state);
6264#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006265}
6266
Oliver Endrissebc7de22011-07-03 13:49:44 -03006267static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006268{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006269 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006270
6271 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006272 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006273 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006274 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006275 return 0;
6276}
6277
Oliver Endrissebc7de22011-07-03 13:49:44 -03006278static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006279{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006280 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006281
6282 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006283 mutex_unlock(&state->ctlock);
6284 return 0;
6285}
6286
Oliver Endrissebc7de22011-07-03 13:49:44 -03006287static int drxk_t_get_frontend(struct dvb_frontend *fe,
6288 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006289{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006290 dprintk(1, "\n");
6291
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006292 return 0;
6293}
6294
6295static struct dvb_frontend_ops drxk_c_ops = {
6296 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006297 .name = "DRXK DVB-C",
6298 .type = FE_QAM,
6299 .frequency_stepsize = 62500,
6300 .frequency_min = 47000000,
6301 .frequency_max = 862000000,
6302 .symbol_rate_min = 870000,
6303 .symbol_rate_max = 11700000,
6304 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6305 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006306 .release = drxk_c_release,
6307 .init = drxk_c_init,
6308 .sleep = drxk_c_sleep,
6309 .i2c_gate_ctrl = drxk_gate_ctrl,
6310
6311 .set_frontend = drxk_set_parameters,
6312 .get_frontend = drxk_c_get_frontend,
6313 .get_tune_settings = drxk_c_get_tune_settings,
6314
6315 .read_status = drxk_read_status,
6316 .read_ber = drxk_read_ber,
6317 .read_signal_strength = drxk_read_signal_strength,
6318 .read_snr = drxk_read_snr,
6319 .read_ucblocks = drxk_read_ucblocks,
6320};
6321
6322static struct dvb_frontend_ops drxk_t_ops = {
6323 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006324 .name = "DRXK DVB-T",
6325 .type = FE_OFDM,
6326 .frequency_min = 47125000,
6327 .frequency_max = 865000000,
6328 .frequency_stepsize = 166667,
6329 .frequency_tolerance = 0,
6330 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6331 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6332 FE_CAN_FEC_AUTO |
6333 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6334 FE_CAN_QAM_AUTO |
6335 FE_CAN_TRANSMISSION_MODE_AUTO |
6336 FE_CAN_GUARD_INTERVAL_AUTO |
6337 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006338 .release = drxk_t_release,
6339 .init = drxk_t_init,
6340 .sleep = drxk_t_sleep,
6341 .i2c_gate_ctrl = drxk_gate_ctrl,
6342
6343 .set_frontend = drxk_set_parameters,
6344 .get_frontend = drxk_t_get_frontend,
6345
6346 .read_status = drxk_read_status,
6347 .read_ber = drxk_read_ber,
6348 .read_signal_strength = drxk_read_signal_strength,
6349 .read_snr = drxk_read_snr,
6350 .read_ucblocks = drxk_read_ucblocks,
6351};
6352
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006353struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6354 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006355 struct dvb_frontend **fe_t)
6356{
6357 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006358 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006359
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006360 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006361 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006362 if (!state)
6363 return NULL;
6364
Oliver Endrissebc7de22011-07-03 13:49:44 -03006365 state->i2c = i2c;
6366 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006367 state->single_master = config->single_master;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006368
6369 mutex_init(&state->mutex);
6370 mutex_init(&state->ctlock);
6371
Oliver Endrissebc7de22011-07-03 13:49:44 -03006372 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6373 sizeof(struct dvb_frontend_ops));
6374 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6375 sizeof(struct dvb_frontend_ops));
6376 state->c_frontend.demodulator_priv = state;
6377 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006378
6379 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006380 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006381 goto error;
6382 *fe_t = &state->t_frontend;
6383 return &state->c_frontend;
6384
6385error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006386 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006387 kfree(state);
6388 return NULL;
6389}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006390EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006391
6392MODULE_DESCRIPTION("DRX-K driver");
6393MODULE_AUTHOR("Ralph Metzler");
6394MODULE_LICENSE("GPL");