blob: c4b35a5638cddf45246938104b9e323efc1dbbc4 [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 Chehab5e66b872011-07-09 09:50:21 -03001391 status = write_block(state, Address, BlockSize, pSrc);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001392 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001393 break;
1394 pSrc += BlockSize;
1395 offset += BlockSize;
1396 }
1397 return status;
1398}
1399
1400static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1401{
1402 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001403 u16 data = 0;
1404 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001405 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1406 unsigned long end;
1407
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001408 dprintk(1, "\n");
1409
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001410 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001411 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001412 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1413 }
1414
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001415 status = (read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001416
1417 if (data == desiredStatus) {
1418 /* tokenring already has correct status */
1419 return status;
1420 }
1421 /* Disable/enable dvbt tokenring bridge */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001422 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001423 write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001424
Oliver Endrissebc7de22011-07-03 13:49:44 -03001425 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001426 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001427 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001428 if (status < 0)
1429 break;
1430 } while ((data != desiredStatus) && ((time_is_after_jiffies(end))));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001431 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001432 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001433 return -1;
1434 }
1435 return status;
1436}
1437
1438static int MPEGTSStop(struct drxk_state *state)
1439{
1440 int status = 0;
1441 u16 fecOcSncMode = 0;
1442 u16 fecOcIprMode = 0;
1443
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001444 dprintk(1, "\n");
1445
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001446 do {
1447 /* Gracefull shutdown (byte boundaries) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001448 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001449 if (status < 0)
1450 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001451 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001452 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001453 if (status < 0)
1454 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001455
1456 /* Suppress MCLK during absence of data */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001457 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001458 if (status < 0)
1459 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001460 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001461 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001462 if (status < 0)
1463 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001464 } while (0);
1465 return status;
1466}
1467
1468static int scu_command(struct drxk_state *state,
1469 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001470 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001471{
1472#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1473#error DRXK register mapping no longer compatible with this routine!
1474#endif
1475 u16 curCmd = 0;
1476 int status;
1477 unsigned long end;
1478
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001479 dprintk(1, "\n");
1480
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001481 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1482 ((resultLen > 0) && (result == NULL)))
1483 return -1;
1484
1485 mutex_lock(&state->mutex);
1486 do {
1487 /* assume that the command register is ready
1488 since it is checked afterwards */
1489 u8 buffer[34];
1490 int cnt = 0, ii;
1491
Oliver Endrissebc7de22011-07-03 13:49:44 -03001492 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001493 buffer[cnt++] = (parameter[ii] & 0xFF);
1494 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1495 }
1496 buffer[cnt++] = (cmd & 0xFF);
1497 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1498
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001499 write_block(state, SCU_RAM_PARAM_0__A -
1500 (parameterLen - 1), cnt, buffer);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001501 /* Wait until SCU has processed command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001502 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001503 do {
1504 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001505 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001506 if (status < 0)
1507 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001508 } while (!(curCmd == DRX_SCU_READY)
1509 && (time_is_after_jiffies(end)));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001510 if (curCmd != DRX_SCU_READY) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001511 printk(KERN_ERR "drxk: SCU not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001512 mutex_unlock(&state->mutex);
1513 return -1;
1514 }
1515 /* read results */
1516 if ((resultLen > 0) && (result != NULL)) {
1517 s16 err;
1518 int ii;
1519
Oliver Endrissebc7de22011-07-03 13:49:44 -03001520 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001521 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001522 if (status < 0)
1523 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001524 }
1525
1526 /* Check if an error was reported by SCU */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001527 err = (s16) result[0];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001528
1529 /* check a few fixed error codes */
1530 if (err == SCU_RESULT_UNKSTD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001531 printk(KERN_ERR "drxk: SCU_RESULT_UNKSTD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001532 mutex_unlock(&state->mutex);
1533 return -1;
1534 } else if (err == SCU_RESULT_UNKCMD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001535 printk(KERN_ERR "drxk: SCU_RESULT_UNKCMD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001536 mutex_unlock(&state->mutex);
1537 return -1;
1538 }
1539 /* here it is assumed that negative means error,
1540 and positive no error */
1541 else if (err < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001542 printk(KERN_ERR "drxk: %s ERROR\n", __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001543 mutex_unlock(&state->mutex);
1544 return -1;
1545 }
1546 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001547 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001548 mutex_unlock(&state->mutex);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001549 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001550 printk(KERN_ERR "drxk: %s: status = %d\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001551
1552 return status;
1553}
1554
1555static int SetIqmAf(struct drxk_state *state, bool active)
1556{
1557 u16 data = 0;
1558 int status;
1559
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001560 dprintk(1, "\n");
1561
Oliver Endrissebc7de22011-07-03 13:49:44 -03001562 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001563 /* Configure IQM */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001564 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001565 if (status < 0)
1566 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001567 if (!active) {
1568 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1569 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1570 | IQM_AF_STDBY_STDBY_PD_STANDBY
1571 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
Oliver Endrissebc7de22011-07-03 13:49:44 -03001572 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1573 } else { /* active */
1574
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001575 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1576 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1577 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1578 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1579 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
Oliver Endrissebc7de22011-07-03 13:49:44 -03001580 );
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001581 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001582 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001583 if (status < 0)
1584 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001585 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001586 return status;
1587}
1588
Oliver Endrissebc7de22011-07-03 13:49:44 -03001589static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001590{
1591 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001592 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001593
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001594 dprintk(1, "\n");
1595
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001596 /* Check arguments */
1597 if (mode == NULL)
1598 return -1;
1599
1600 switch (*mode) {
1601 case DRX_POWER_UP:
1602 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1603 break;
1604 case DRXK_POWER_DOWN_OFDM:
1605 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1606 break;
1607 case DRXK_POWER_DOWN_CORE:
1608 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1609 break;
1610 case DRXK_POWER_DOWN_PLL:
1611 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1612 break;
1613 case DRX_POWER_DOWN:
1614 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1615 break;
1616 default:
1617 /* Unknow sleep mode */
1618 return -1;
1619 break;
1620 }
1621
1622 /* If already in requested power mode, do nothing */
1623 if (state->m_currentPowerMode == *mode)
1624 return 0;
1625
1626 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001627 if (state->m_currentPowerMode != DRX_POWER_UP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001628 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001629 status = PowerUpDevice(state);
1630 if (status < 0)
1631 break;
1632 status = DVBTEnableOFDMTokenRing(state, true);
1633 if (status < 0)
1634 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001635 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001636 }
1637
1638 if (*mode == DRX_POWER_UP) {
1639 /* Restore analog & pin configuartion */
1640 } else {
1641 /* Power down to requested mode */
1642 /* Backup some register settings */
1643 /* Set pins with possible pull-ups connected
1644 to them in input mode */
1645 /* Analog power down */
1646 /* ADC power down */
1647 /* Power down device */
1648 /* stop all comm_exec */
1649 /* Stop and power down previous standard */
1650 do {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001651 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001652 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001653 status = MPEGTSStop(state);
1654 if (status < 0)
1655 break;
1656 status = PowerDownDVBT(state, false);
1657 if (status < 0)
1658 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001659 break;
1660 case OM_QAM_ITU_A:
1661 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001662 status = MPEGTSStop(state);
1663 if (status < 0)
1664 break;
1665 status = PowerDownQAM(state);
1666 if (status < 0)
1667 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001668 break;
1669 default:
1670 break;
1671 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001672 status = DVBTEnableOFDMTokenRing(state, false);
1673 if (status < 0)
1674 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001675 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001676 if (status < 0)
1677 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001678 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001679 if (status < 0)
1680 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001681
Oliver Endrissebc7de22011-07-03 13:49:44 -03001682 if (*mode != DRXK_POWER_DOWN_OFDM) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001683 state->m_HICfgCtrl |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03001684 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001685 status = HI_CfgCommand(state);
1686 if (status < 0)
1687 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001688 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001689 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001690 }
1691 state->m_currentPowerMode = *mode;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001692 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001693}
1694
1695static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1696{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001697 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001698 u16 cmdResult = 0;
1699 u16 data = 0;
1700 int status;
1701
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001702 dprintk(1, "\n");
1703
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001704 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001705 status = read16(state, SCU_COMM_EXEC__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001706 if (status < 0)
1707 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001708 if (data == SCU_COMM_EXEC_ACTIVE) {
1709 /* Send OFDM stop command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001710 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
1711 if (status < 0)
1712 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001713 /* Send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001714 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1715 if (status < 0)
1716 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001717 }
1718
1719 /* Reset datapath for OFDM, processors first */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001720 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001721 if (status < 0)
1722 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001723 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001724 if (status < 0)
1725 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001726 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001727 if (status < 0)
1728 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001729
1730 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001731 status = SetIqmAf(state, false);
1732 if (status < 0)
1733 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001734
1735 /* powerdown to OFDM mode */
1736 if (setPowerMode) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001737 status = CtrlPowerMode(state, &powerMode);
1738 if (status < 0)
1739 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001740 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001741 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001742 return status;
1743}
1744
Oliver Endrissebc7de22011-07-03 13:49:44 -03001745static int SetOperationMode(struct drxk_state *state,
1746 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001747{
1748 int status = 0;
1749
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001750 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001751 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001752 Stop and power down previous standard
1753 TODO investigate total power down instead of partial
1754 power down depending on "previous" standard.
1755 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001756 do {
1757 /* disable HW lock indicator */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001758 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001759 if (status < 0)
1760 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001761
1762 if (state->m_OperationMode != oMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001763 switch (state->m_OperationMode) {
1764 /* OM_NONE was added for start up */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001765 case OM_NONE:
1766 break;
1767 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001768 status = MPEGTSStop(state);
1769 if (status < 0)
1770 break;
1771 status = PowerDownDVBT(state, true);
1772 if (status < 0)
1773 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001774 state->m_OperationMode = OM_NONE;
1775 break;
1776 case OM_QAM_ITU_B:
1777 status = -1;
1778 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001779 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001780 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001781 status = MPEGTSStop(state);
1782 if (status < 0)
1783 break;
1784 status = PowerDownQAM(state);
1785 if (status < 0)
1786 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001787 state->m_OperationMode = OM_NONE;
1788 break;
1789 default:
1790 status = -1;
1791 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001792 status = status;
1793 if (status < 0)
1794 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001795
1796 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001797 Power up new standard
1798 */
1799 switch (oMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001800 case OM_DVBT:
1801 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001802 status = SetDVBTStandard(state, oMode);
1803 if (status < 0)
1804 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001805 break;
1806 case OM_QAM_ITU_B:
1807 status = -1;
1808 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001809 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001810 case OM_QAM_ITU_C:
1811 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001812 status = SetQAMStandard(state, oMode);
1813 if (status < 0)
1814 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001815 break;
1816 default:
1817 status = -1;
1818 }
1819 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001820 status = status;
1821 if (status < 0)
1822 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001823 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001824 return 0;
1825}
1826
1827static int Start(struct drxk_state *state, s32 offsetFreq,
1828 s32 IntermediateFrequency)
1829{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001830 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001831
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001832 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001833 do {
1834 u16 IFreqkHz;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001835 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001836
1837 if (state->m_DrxkState != DRXK_STOPPED &&
1838 state->m_DrxkState != DRXK_DTV_STARTED) {
1839 status = -1;
1840 break;
1841 }
1842 state->m_bMirrorFreqSpect =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001843 (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001844
1845 if (IntermediateFrequency < 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001846 state->m_bMirrorFreqSpect =
1847 !state->m_bMirrorFreqSpect;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001848 IntermediateFrequency = -IntermediateFrequency;
1849 }
1850
Oliver Endrissebc7de22011-07-03 13:49:44 -03001851 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001852 case OM_QAM_ITU_A:
1853 case OM_QAM_ITU_C:
1854 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001855 status = SetQAM(state, IFreqkHz, OffsetkHz);
1856 if (status < 0)
1857 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001858 state->m_DrxkState = DRXK_DTV_STARTED;
1859 break;
1860 case OM_DVBT:
1861 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001862 status = MPEGTSStop(state);
1863 if (status < 0)
1864 break;
1865 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1866 if (status < 0)
1867 break;
1868 status = DVBTStart(state);
1869 if (status < 0)
1870 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001871 state->m_DrxkState = DRXK_DTV_STARTED;
1872 break;
1873 default:
1874 break;
1875 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001876 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001877 return status;
1878}
1879
1880static int ShutDown(struct drxk_state *state)
1881{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001882 dprintk(1, "\n");
1883
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001884 MPEGTSStop(state);
1885 return 0;
1886}
1887
Oliver Endrissebc7de22011-07-03 13:49:44 -03001888static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1889 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001890{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001891 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001892
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001893 dprintk(1, "\n");
1894
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001895 if (pLockStatus == NULL)
1896 return -1;
1897
1898 *pLockStatus = NOT_LOCKED;
1899
1900 /* define the SCU command code */
1901 switch (state->m_OperationMode) {
1902 case OM_QAM_ITU_A:
1903 case OM_QAM_ITU_B:
1904 case OM_QAM_ITU_C:
1905 status = GetQAMLockStatus(state, pLockStatus);
1906 break;
1907 case OM_DVBT:
1908 status = GetDVBTLockStatus(state, pLockStatus);
1909 break;
1910 default:
1911 break;
1912 }
1913 return status;
1914}
1915
1916static int MPEGTSStart(struct drxk_state *state)
1917{
1918 int status = 0;
1919
1920 u16 fecOcSncMode = 0;
1921
1922 do {
1923 /* Allow OC to sync again */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001924 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001925 if (status < 0)
1926 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001927 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001928 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001929 if (status < 0)
1930 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001931 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001932 if (status < 0)
1933 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001934 } while (0);
1935 return status;
1936}
1937
1938static int MPEGTSDtoInit(struct drxk_state *state)
1939{
1940 int status = -1;
1941
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001942 dprintk(1, "\n");
1943
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001944 do {
1945 /* Rate integration settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001946 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001947 if (status < 0)
1948 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001949 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001950 if (status < 0)
1951 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001952 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001953 if (status < 0)
1954 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001955 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
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_AVR_PARM_B__A, 0x0006);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001959 if (status < 0)
1960 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001961 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001962 if (status < 0)
1963 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001964 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
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_COUNT__A, 0x03F4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001968 if (status < 0)
1969 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001970
1971 /* Additional configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001972 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001973 if (status < 0)
1974 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001975 status = write16(state, FEC_OC_SNC_LWM__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001976 if (status < 0)
1977 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001978 status = write16(state, FEC_OC_SNC_HWM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001979 if (status < 0)
1980 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001981 } while (0);
1982 return status;
1983}
1984
Oliver Endrissebc7de22011-07-03 13:49:44 -03001985static int MPEGTSDtoSetup(struct drxk_state *state,
1986 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001987{
1988 int status = -1;
1989
Oliver Endrissebc7de22011-07-03 13:49:44 -03001990 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
1991 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
1992 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
1993 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
1994 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
1995 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
1996 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001997 u16 fecOcTmdMode = 0;
1998 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001999 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002000 bool staticCLK = false;
2001
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002002 dprintk(1, "\n");
2003
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002004 do {
2005 /* Check insertion of the Reed-Solomon parity bytes */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002006 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002007 if (status < 0)
2008 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002009 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002010 if (status < 0)
2011 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002012 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002013 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2014 if (state->m_insertRSByte == true) {
2015 /* enable parity symbol forward */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002016 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002017 /* MVAL disable during parity bytes */
2018 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2019 /* TS burst length to 204 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002020 fecOcDtoBurstLen = 204;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002021 }
2022
2023 /* Check serial or parrallel output */
2024 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2025 if (state->m_enableParallel == false) {
2026 /* MPEG data output is serial -> set ipr_mode[0] */
2027 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2028 }
2029
2030 switch (oMode) {
2031 case OM_DVBT:
2032 maxBitRate = state->m_DVBTBitrate;
2033 fecOcTmdMode = 3;
2034 fecOcRcnCtlRate = 0xC00000;
2035 staticCLK = state->m_DVBTStaticCLK;
2036 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002037 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002038 case OM_QAM_ITU_C:
2039 fecOcTmdMode = 0x0004;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002040 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002041 maxBitRate = state->m_DVBCBitrate;
2042 staticCLK = state->m_DVBCStaticCLK;
2043 break;
2044 default:
2045 status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002046 } /* switch (standard) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002047 status = status;
2048 if (status < 0)
2049 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002050
2051 /* Configure DTO's */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002052 if (staticCLK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002053 u32 bitRate = 0;
2054
2055 /* Rational DTO for MCLK source (static MCLK rate),
2056 Dynamic DTO for optimal grouping
2057 (avoid intra-packet gaps),
2058 DTO offset enable to sync TS burst with MSTRT */
2059 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2060 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2061 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2062 FEC_OC_FCT_MODE_VIRT_ENA__M);
2063
2064 /* Check user defined bitrate */
2065 bitRate = maxBitRate;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002066 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002067 bitRate = 75900000UL;
2068 }
2069 /* Rational DTO period:
2070 dto_period = (Fsys / bitrate) - 2
2071
2072 Result should be floored,
2073 to make sure >= requested bitrate
Oliver Endrissebc7de22011-07-03 13:49:44 -03002074 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002075 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2076 * 1000) / bitRate);
2077 if (fecOcDtoPeriod <= 2)
2078 fecOcDtoPeriod = 0;
2079 else
2080 fecOcDtoPeriod -= 2;
2081 fecOcTmdIntUpdRate = 8;
2082 } else {
2083 /* (commonAttr->staticCLK == false) => dynamic mode */
2084 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2085 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2086 fecOcTmdIntUpdRate = 5;
2087 }
2088
2089 /* Write appropriate registers with requested configuration */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002090 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002091 if (status < 0)
2092 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002093 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002094 if (status < 0)
2095 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002096 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
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_FCT_MODE__A, fecOcFctMode);
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_MODE__A, fecOcRegMode);
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_IPR_MODE__A, fecOcRegIprMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002106 if (status < 0)
2107 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002108
2109 /* Rate integration settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002110 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002111 if (status < 0)
2112 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002113 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002114 if (status < 0)
2115 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002116 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002117 if (status < 0)
2118 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002119 } while (0);
2120 return status;
2121}
2122
2123static int MPEGTSConfigurePolarity(struct drxk_state *state)
2124{
2125 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002126 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002127
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002128 dprintk(1, "\n");
2129
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002130 /* Data mask for the output data byte */
2131 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002132 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2133 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2134 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2135 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002136
2137 /* Control selective inversion of output bits */
2138 fecOcRegIprInvert &= (~(InvertDataMask));
2139 if (state->m_invertDATA == true)
2140 fecOcRegIprInvert |= InvertDataMask;
2141 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2142 if (state->m_invertERR == true)
2143 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2144 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2145 if (state->m_invertSTR == true)
2146 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2147 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2148 if (state->m_invertVAL == true)
2149 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2150 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2151 if (state->m_invertCLK == true)
2152 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002153 status = write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002154 return status;
2155}
2156
2157#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2158
2159static int SetAgcRf(struct drxk_state *state,
2160 struct SCfgAgc *pAgcCfg, bool isDTV)
2161{
2162 int status = 0;
2163 struct SCfgAgc *pIfAgcSettings;
2164
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002165 dprintk(1, "\n");
2166
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002167 if (pAgcCfg == NULL)
2168 return -1;
2169
2170 do {
2171 u16 data = 0;
2172
2173 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002174 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002175
2176 /* Enable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002177 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002178 if (status < 0)
2179 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002180 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002181 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002182 if (status < 0)
2183 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002184
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002185 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002186 if (status < 0)
2187 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002188
2189 /* Enable SCU RF AGC loop */
2190 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2191
2192 /* Polarity */
2193 if (state->m_RfAgcPol)
2194 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2195 else
2196 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002197 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002198 if (status < 0)
2199 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002200
2201 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002202 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002203 if (status < 0)
2204 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002205
2206 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2207 data |= (~(pAgcCfg->speed <<
2208 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2209 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2210
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002211 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002212 if (status < 0)
2213 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002214
2215 if (IsDVBT(state))
2216 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2217 else if (IsQAM(state))
2218 pIfAgcSettings = &state->m_qamIfAgcCfg;
2219 else
2220 pIfAgcSettings = &state->m_atvIfAgcCfg;
2221 if (pIfAgcSettings == NULL)
2222 return -1;
2223
2224 /* Set TOP, only if IF-AGC is in AUTO mode */
2225 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002226 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002227 if (status < 0)
2228 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002229
2230 /* Cut-Off current */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002231 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002232 if (status < 0)
2233 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002234
2235 /* Max. output level */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002236 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002237 if (status < 0)
2238 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002239
2240 break;
2241
2242 case DRXK_AGC_CTRL_USER:
2243 /* Enable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002244 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002245 if (status < 0)
2246 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002247 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002248 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002249 if (status < 0)
2250 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002251
2252 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002253 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002254 if (status < 0)
2255 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002256 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2257 if (state->m_RfAgcPol)
2258 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2259 else
2260 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002261 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002262 if (status < 0)
2263 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002264
2265 /* SCU c.o.c. to 0, enabling full control range */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002266 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002267 if (status < 0)
2268 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002269
2270 /* Write value to output pin */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002271 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002272 if (status < 0)
2273 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002274 break;
2275
Oliver Endrissebc7de22011-07-03 13:49:44 -03002276 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002277 /* Disable RF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002278 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002279 if (status < 0)
2280 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002281 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002282 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002283 if (status < 0)
2284 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002285
2286 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002287 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002288 if (status < 0)
2289 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002290 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002291 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002292 if (status < 0)
2293 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002294 break;
2295
2296 default:
2297 return -1;
2298
Oliver Endrissebc7de22011-07-03 13:49:44 -03002299 } /* switch (agcsettings->ctrlMode) */
2300 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002301 return status;
2302}
2303
2304#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2305
Oliver Endrissebc7de22011-07-03 13:49:44 -03002306static int SetAgcIf(struct drxk_state *state,
2307 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002308{
2309 u16 data = 0;
2310 int status = 0;
2311 struct SCfgAgc *pRfAgcSettings;
2312
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002313 dprintk(1, "\n");
2314
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002315 do {
2316 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002317 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002318
2319 /* Enable IF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002320 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002321 if (status < 0)
2322 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002323 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002324 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002325 if (status < 0)
2326 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002327
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002328 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002329 if (status < 0)
2330 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002331
2332 /* Enable SCU IF AGC loop */
2333 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2334
2335 /* Polarity */
2336 if (state->m_IfAgcPol)
2337 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2338 else
2339 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002340 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002341 if (status < 0)
2342 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002343
2344 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002345 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002346 if (status < 0)
2347 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002348 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2349 data |= (~(pAgcCfg->speed <<
2350 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2351 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2352
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002353 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002354 if (status < 0)
2355 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002356
2357 if (IsQAM(state))
2358 pRfAgcSettings = &state->m_qamRfAgcCfg;
2359 else
2360 pRfAgcSettings = &state->m_atvRfAgcCfg;
2361 if (pRfAgcSettings == NULL)
2362 return -1;
2363 /* Restore TOP */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002364 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002365 if (status < 0)
2366 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002367 break;
2368
Oliver Endrissebc7de22011-07-03 13:49:44 -03002369 case DRXK_AGC_CTRL_USER:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002370
2371 /* Enable IF AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002372 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002373 if (status < 0)
2374 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002375 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002376 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002377 if (status < 0)
2378 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002379
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002380 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002381 if (status < 0)
2382 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002383
2384 /* Disable SCU IF AGC loop */
2385 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2386
2387 /* Polarity */
2388 if (state->m_IfAgcPol)
2389 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2390 else
2391 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002392 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002393 if (status < 0)
2394 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002395
2396 /* Write value to output pin */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002397 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002398 if (status < 0)
2399 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002400 break;
2401
Oliver Endrissebc7de22011-07-03 13:49:44 -03002402 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002403
2404 /* Disable If AGC DAC */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002405 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002406 if (status < 0)
2407 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002408 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002409 status = write16(state, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002410 if (status < 0)
2411 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002412
2413 /* Disable SCU IF AGC loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002414 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002415 if (status < 0)
2416 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002417 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002418 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002419 if (status < 0)
2420 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002421 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002422 } /* switch (agcSettingsIf->ctrlMode) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002423
2424 /* always set the top to support
2425 configurations without if-loop */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002426 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002427 if (status < 0)
2428 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002429
2430
Oliver Endrissebc7de22011-07-03 13:49:44 -03002431 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002432 return status;
2433}
2434
2435static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2436{
2437 u16 agcDacLvl;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002438 int status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002439
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002440 dprintk(1, "\n");
2441
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002442 *pValue = 0;
2443
Oliver Endrissebc7de22011-07-03 13:49:44 -03002444 if (status == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002445 u16 Level = 0;
2446 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2447 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2448 if (Level < 14000)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002449 *pValue = (14000 - Level) / 4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002450 else
2451 *pValue = 0;
2452 }
2453 return status;
2454}
2455
Oliver Endrissebc7de22011-07-03 13:49:44 -03002456static int GetQAMSignalToNoise(struct drxk_state *state,
2457 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002458{
2459 int status = 0;
2460
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002461 dprintk(1, "\n");
2462
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002463 do {
2464 /* MER calculation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002465 u16 qamSlErrPower = 0; /* accum. error between
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002466 raw and sliced symbols */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002467 u32 qamSlSigPower = 0; /* used for MER, depends of
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002468 QAM constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002469 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002470
2471 /* get the register value needed for MER */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002472 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002473 if (status < 0)
2474 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002475
Oliver Endrissebc7de22011-07-03 13:49:44 -03002476 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002477 case QAM_16:
2478 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2479 break;
2480 case QAM_32:
2481 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2482 break;
2483 case QAM_64:
2484 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2485 break;
2486 case QAM_128:
2487 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2488 break;
2489 default:
2490 case QAM_256:
2491 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2492 break;
2493 }
2494
2495 if (qamSlErrPower > 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002496 qamSlMer = Log10Times100(qamSlSigPower) -
2497 Log10Times100((u32) qamSlErrPower);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002498 }
2499 *pSignalToNoise = qamSlMer;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002500 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002501 return status;
2502}
2503
Oliver Endrissebc7de22011-07-03 13:49:44 -03002504static int GetDVBTSignalToNoise(struct drxk_state *state,
2505 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002506{
2507 int status = 0;
2508
Oliver Endrissebc7de22011-07-03 13:49:44 -03002509 u16 regData = 0;
2510 u32 EqRegTdSqrErrI = 0;
2511 u32 EqRegTdSqrErrQ = 0;
2512 u16 EqRegTdSqrErrExp = 0;
2513 u16 EqRegTdTpsPwrOfs = 0;
2514 u16 EqRegTdReqSmbCnt = 0;
2515 u32 tpsCnt = 0;
2516 u32 SqrErrIQ = 0;
2517 u32 a = 0;
2518 u32 b = 0;
2519 u32 c = 0;
2520 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002521 u16 transmissionParams = 0;
2522
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002523 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002524 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002525 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002526 if (status < 0)
2527 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002528 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002529 if (status < 0)
2530 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002531 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
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_SQR_ERR_I__A, &regData);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002535 if (status < 0)
2536 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002537 /* Extend SQR_ERR_I operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002538 EqRegTdSqrErrI = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002539 if ((EqRegTdSqrErrExp > 11) &&
2540 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2541 EqRegTdSqrErrI += 0x00010000UL;
2542 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002543 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002544 if (status < 0)
2545 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002546 /* Extend SQR_ERR_Q operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002547 EqRegTdSqrErrQ = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002548 if ((EqRegTdSqrErrExp > 11) &&
2549 (EqRegTdSqrErrQ < 0x00000FFFUL))
2550 EqRegTdSqrErrQ += 0x00010000UL;
2551
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002552 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002553 if (status < 0)
2554 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002555
2556 /* Check input data for MER */
2557
2558 /* MER calculation (in 0.1 dB) without math.h */
2559 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2560 iMER = 0;
2561 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2562 /* No error at all, this must be the HW reset value
2563 * Apparently no first measurement yet
2564 * Set MER to 0.0 */
2565 iMER = 0;
2566 } else {
2567 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03002568 EqRegTdSqrErrExp;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002569 if ((transmissionParams &
2570 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2571 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2572 tpsCnt = 17;
2573 else
2574 tpsCnt = 68;
2575
2576 /* IMER = 100 * log10 (x)
2577 where x = (EqRegTdTpsPwrOfs^2 *
2578 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2579
2580 => IMER = a + b -c
2581 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2582 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2583 c = 100 * log10 (SqrErrIQ)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002584 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002585
2586 /* log(x) x = 9bits * 9bits->18 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002587 a = Log10Times100(EqRegTdTpsPwrOfs *
2588 EqRegTdTpsPwrOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002589 /* log(x) x = 16bits * 7bits->23 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002590 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002591 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2592 c = Log10Times100(SqrErrIQ);
2593
2594 iMER = a + b;
2595 /* No negative MER, clip to zero */
2596 if (iMER > c)
2597 iMER -= c;
2598 else
2599 iMER = 0;
2600 }
2601 *pSignalToNoise = iMER;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002602 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002603
2604 return status;
2605}
2606
2607static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2608{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002609 dprintk(1, "\n");
2610
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002611 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002612 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002613 case OM_DVBT:
2614 return GetDVBTSignalToNoise(state, pSignalToNoise);
2615 case OM_QAM_ITU_A:
2616 case OM_QAM_ITU_C:
2617 return GetQAMSignalToNoise(state, pSignalToNoise);
2618 default:
2619 break;
2620 }
2621 return 0;
2622}
2623
2624#if 0
2625static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2626{
2627 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2628 int status = 0;
2629
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002630 dprintk(1, "\n");
2631
Oliver Endrissebc7de22011-07-03 13:49:44 -03002632 static s32 QE_SN[] = {
2633 51, /* QPSK 1/2 */
2634 69, /* QPSK 2/3 */
2635 79, /* QPSK 3/4 */
2636 89, /* QPSK 5/6 */
2637 97, /* QPSK 7/8 */
2638 108, /* 16-QAM 1/2 */
2639 131, /* 16-QAM 2/3 */
2640 146, /* 16-QAM 3/4 */
2641 156, /* 16-QAM 5/6 */
2642 160, /* 16-QAM 7/8 */
2643 165, /* 64-QAM 1/2 */
2644 187, /* 64-QAM 2/3 */
2645 202, /* 64-QAM 3/4 */
2646 216, /* 64-QAM 5/6 */
2647 225, /* 64-QAM 7/8 */
2648 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002649
2650 *pQuality = 0;
2651
2652 do {
2653 s32 SignalToNoise = 0;
2654 u16 Constellation = 0;
2655 u16 CodeRate = 0;
2656 u32 SignalToNoiseRel;
2657 u32 BERQuality;
2658
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002659 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2660 if (status < 0)
2661 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002662 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002663 if (status < 0)
2664 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002665 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2666
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002667 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002668 if (status < 0)
2669 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002670 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2671
2672 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2673 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2674 break;
2675 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002676 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002677 BERQuality = 100;
2678
Oliver Endrissebc7de22011-07-03 13:49:44 -03002679 if (SignalToNoiseRel < -70)
2680 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002681 else if (SignalToNoiseRel < 30)
2682 *pQuality = ((SignalToNoiseRel + 70) *
2683 BERQuality) / 100;
2684 else
2685 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002686 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002687 return 0;
2688};
2689
Oliver Endrissebc7de22011-07-03 13:49:44 -03002690static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002691{
2692 int status = 0;
2693 *pQuality = 0;
2694
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002695 dprintk(1, "\n");
2696
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002697 do {
2698 u32 SignalToNoise = 0;
2699 u32 BERQuality = 100;
2700 u32 SignalToNoiseRel = 0;
2701
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002702 status = GetQAMSignalToNoise(state, &SignalToNoise);
2703 if (status < 0)
2704 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002705
Oliver Endrissebc7de22011-07-03 13:49:44 -03002706 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002707 case QAM_16:
2708 SignalToNoiseRel = SignalToNoise - 200;
2709 break;
2710 case QAM_32:
2711 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002712 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002713 case QAM_64:
2714 SignalToNoiseRel = SignalToNoise - 260;
2715 break;
2716 case QAM_128:
2717 SignalToNoiseRel = SignalToNoise - 290;
2718 break;
2719 default:
2720 case QAM_256:
2721 SignalToNoiseRel = SignalToNoise - 320;
2722 break;
2723 }
2724
2725 if (SignalToNoiseRel < -70)
2726 *pQuality = 0;
2727 else if (SignalToNoiseRel < 30)
2728 *pQuality = ((SignalToNoiseRel + 70) *
2729 BERQuality) / 100;
2730 else
2731 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002732 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002733
2734 return status;
2735}
2736
2737static int GetQuality(struct drxk_state *state, s32 *pQuality)
2738{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002739 dprintk(1, "\n");
2740
Oliver Endrissebc7de22011-07-03 13:49:44 -03002741 switch (state->m_OperationMode) {
2742 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002743 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002744 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002745 return GetDVBCQuality(state, pQuality);
2746 default:
2747 break;
2748 }
2749
2750 return 0;
2751}
2752#endif
2753
2754/* Free data ram in SIO HI */
2755#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2756#define SIO_HI_RA_RAM_USR_END__A 0x420060
2757
2758#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2759#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2760#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2761#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2762
2763#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2764#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2765#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2766
2767static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2768{
2769 int status;
2770
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002771 dprintk(1, "\n");
2772
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002773 if (state->m_DrxkState == DRXK_UNINITIALIZED)
2774 return -1;
2775 if (state->m_DrxkState == DRXK_POWERED_DOWN)
2776 return -1;
2777
2778 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002779 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 -03002780 if (status < 0)
2781 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002782 if (bEnableBridge) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002783 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 -03002784 if (status < 0)
2785 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002786 } else {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002787 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 -03002788 if (status < 0)
2789 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002790 }
2791
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002792 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2793 if (status < 0)
2794 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002795 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002796 return status;
2797}
2798
Oliver Endrissebc7de22011-07-03 13:49:44 -03002799static int SetPreSaw(struct drxk_state *state,
2800 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002801{
2802 int status;
2803
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002804 dprintk(1, "\n");
2805
Oliver Endrissebc7de22011-07-03 13:49:44 -03002806 if ((pPreSawCfg == NULL)
2807 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002808 return -1;
2809
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002810 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002811 return status;
2812}
2813
2814static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002815 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002816{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002817 u16 blStatus = 0;
2818 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2819 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2820 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002821 unsigned long end;
2822
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002823 dprintk(1, "\n");
2824
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002825 mutex_lock(&state->mutex);
2826 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002827 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002828 if (status < 0)
2829 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002830 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002831 if (status < 0)
2832 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002833 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002834 if (status < 0)
2835 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002836 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
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_SRC_LEN__A, nrOfElements);
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_ENABLE__A, SIO_BL_ENABLE_ON);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002843 if (status < 0)
2844 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002845
Oliver Endrissebc7de22011-07-03 13:49:44 -03002846 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002847 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002848 status = read16(state, SIO_BL_STATUS__A, &blStatus);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002849 if (status < 0)
2850 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002851 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002852 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03002853 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002854 mutex_unlock(&state->mutex);
2855 return -1;
2856 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03002857 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002858 mutex_unlock(&state->mutex);
2859 return status;
2860
2861}
2862
Oliver Endrissebc7de22011-07-03 13:49:44 -03002863static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002864{
2865 u16 data = 0;
2866 int status;
2867
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002868 dprintk(1, "\n");
2869
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002870 do {
2871 /* Start measurement */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002872 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002873 if (status < 0)
2874 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002875 status = write16(state, IQM_AF_START_LOCK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002876 if (status < 0)
2877 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002878
2879 *count = 0;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002880 status = read16(state, IQM_AF_PHASE0__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002881 if (status < 0)
2882 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002883 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002884 *count = *count + 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002885 status = read16(state, IQM_AF_PHASE1__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002886 if (status < 0)
2887 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002888 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002889 *count = *count + 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002890 status = read16(state, IQM_AF_PHASE2__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002891 if (status < 0)
2892 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002893 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002894 *count = *count + 1;
2895 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002896 return status;
2897}
2898
2899static int ADCSynchronization(struct drxk_state *state)
2900{
2901 u16 count = 0;
2902 int status;
2903
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002904 dprintk(1, "\n");
2905
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002906 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002907 status = ADCSyncMeasurement(state, &count);
2908 if (status < 0)
2909 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002910
Oliver Endrissebc7de22011-07-03 13:49:44 -03002911 if (count == 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002912 /* Try sampling on a diffrent edge */
2913 u16 clkNeg = 0;
2914
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002915 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002916 if (status < 0)
2917 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002918 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002919 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2920 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2921 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002922 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002923 } else {
2924 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2925 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002926 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002927 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002928 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002929 if (status < 0)
2930 break;
2931 status = ADCSyncMeasurement(state, &count);
2932 if (status < 0)
2933 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002934 }
2935
2936 if (count < 2)
2937 status = -1;
2938 } while (0);
2939 return status;
2940}
2941
2942static int SetFrequencyShifter(struct drxk_state *state,
2943 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002944 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002945{
2946 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002947 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002948 u32 fmFrequencyShift = 0;
2949 bool tunerMirror = !state->m_bMirrorFreqSpect;
2950 u32 adcFreq;
2951 bool adcFlip;
2952 int status;
2953 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002954 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002955 u32 frequencyShift;
2956 bool imageToSelect;
2957
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002958 dprintk(1, "\n");
2959
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002960 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03002961 Program frequency shifter
2962 No need to account for mirroring on RF
2963 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002964 if (isDTV) {
2965 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
2966 (state->m_OperationMode == OM_QAM_ITU_C) ||
2967 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03002968 selectPosImage = true;
2969 else
2970 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002971 }
2972 if (tunerMirror)
2973 /* tuner doesn't mirror */
2974 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03002975 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002976 else
2977 /* tuner mirrors */
2978 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002979 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002980 if (ifFreqActual > samplingFrequency / 2) {
2981 /* adc mirrors */
2982 adcFreq = samplingFrequency - ifFreqActual;
2983 adcFlip = true;
2984 } else {
2985 /* adc doesn't mirror */
2986 adcFreq = ifFreqActual;
2987 adcFlip = false;
2988 }
2989
2990 frequencyShift = adcFreq;
2991 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03002992 adcFlip ^ selectPosImage;
2993 state->m_IqmFsRateOfs =
2994 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002995
2996 if (imageToSelect)
2997 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
2998
2999 /* Program frequency shifter with tuner offset compensation */
3000 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003001 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3002 state->m_IqmFsRateOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003003 return status;
3004}
3005
3006static int InitAGC(struct drxk_state *state, bool isDTV)
3007{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003008 u16 ingainTgt = 0;
3009 u16 ingainTgtMin = 0;
3010 u16 ingainTgtMax = 0;
3011 u16 clpCyclen = 0;
3012 u16 clpSumMin = 0;
3013 u16 clpDirTo = 0;
3014 u16 snsSumMin = 0;
3015 u16 snsSumMax = 0;
3016 u16 clpSumMax = 0;
3017 u16 snsDirTo = 0;
3018 u16 kiInnergainMin = 0;
3019 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003020 u16 ifIaccuHiTgtMin = 0;
3021 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003022 u16 data = 0;
3023 u16 fastClpCtrlDelay = 0;
3024 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003025 int status = 0;
3026
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003027 dprintk(1, "\n");
3028
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003029 do {
3030 /* Common settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003031 snsSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003032 ifIaccuHiTgtMin = 2047;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003033 clpCyclen = 500;
3034 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003035
3036 if (IsQAM(state)) {
3037 /* Standard specific settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003038 clpSumMin = 8;
3039 clpDirTo = (u16) -9;
3040 clpCtrlMode = 0;
3041 snsSumMin = 8;
3042 snsDirTo = (u16) -9;
3043 kiInnergainMin = (u16) -1030;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003044 } else
3045 status = -1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003046 status = (status);
3047 if (status < 0)
3048 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003049 if (IsQAM(state)) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003050 ifIaccuHiTgtMax = 0x2380;
3051 ifIaccuHiTgt = 0x2380;
3052 ingainTgtMin = 0x0511;
3053 ingainTgt = 0x0511;
3054 ingainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003055 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003056 state->m_qamIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003057 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003058 ifIaccuHiTgtMax = 0x1200;
3059 ifIaccuHiTgt = 0x1200;
3060 ingainTgtMin = 13424;
3061 ingainTgt = 13424;
3062 ingainTgtMax = 30000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003063 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003064 state->m_dvbtIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003065 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003066 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003067 if (status < 0)
3068 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003069
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003070 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003071 if (status < 0)
3072 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003073 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003074 if (status < 0)
3075 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003076 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
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_MAX__A, ingainTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003080 if (status < 0)
3081 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003082 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003083 if (status < 0)
3084 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003085 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
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__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003089 if (status < 0)
3090 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003091 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003092 if (status < 0)
3093 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003094 status = write16(state, SCU_RAM_AGC_RF_IACCU_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_RF_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_CLP_SUM_MAX__A, clpSumMax);
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_SNS_SUM_MAX__A, snsSumMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003104 if (status < 0)
3105 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003106
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003107 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003108 if (status < 0)
3109 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003110 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003111 if (status < 0)
3112 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003113 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003114 if (status < 0)
3115 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003116
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003117 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003118 if (status < 0)
3119 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003120 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003121 if (status < 0)
3122 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003123 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003124 if (status < 0)
3125 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003126
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003127 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003128 if (status < 0)
3129 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003130 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003131 if (status < 0)
3132 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003133 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
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_DIR_TO__A, clpDirTo);
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_DIR_TO__A, snsDirTo);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003140 if (status < 0)
3141 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003142 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003143 if (status < 0)
3144 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003145 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
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_MIN__A, 0x0117);
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_MAX__A, 0x0657);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003152 if (status < 0)
3153 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003154 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003155 if (status < 0)
3156 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003157 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003158 if (status < 0)
3159 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003160 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__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_DIR_STP__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003164 if (status < 0)
3165 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003166 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003167 if (status < 0)
3168 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003169 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003170 if (status < 0)
3171 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003172 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__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_DIR_STP__A, 1);
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_CYCLEN__A, 500);
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_KI_CYCLEN__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003182 if (status < 0)
3183 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003184
3185 /* Initialize inner-loop KI gain factors */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003186 status = read16(state, SCU_RAM_AGC_KI__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003187 if (status < 0)
3188 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003189 if (IsQAM(state)) {
3190 data = 0x0657;
3191 data &= ~SCU_RAM_AGC_KI_RF__M;
3192 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3193 data &= ~SCU_RAM_AGC_KI_IF__M;
3194 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3195 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003196 status = write16(state, SCU_RAM_AGC_KI__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003197 if (status < 0)
3198 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003199 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003200 return status;
3201}
3202
Oliver Endrissebc7de22011-07-03 13:49:44 -03003203static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003204{
3205 int status;
3206
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003207 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003208 do {
3209 if (packetErr == NULL) {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003210 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003211 if (status < 0)
3212 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003213 } else {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003214 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003215 if (status < 0)
3216 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003217 }
3218 } while (0);
3219 return status;
3220}
3221
3222static int DVBTScCommand(struct drxk_state *state,
3223 u16 cmd, u16 subcmd,
3224 u16 param0, u16 param1, u16 param2,
3225 u16 param3, u16 param4)
3226{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003227 u16 curCmd = 0;
3228 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003229 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003230 u16 scExec = 0;
3231 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003232
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003233 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003234 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003235 if (scExec != 1) {
3236 /* SC is not running */
3237 return -1;
3238 }
3239
3240 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003241 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003242 do {
3243 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003244 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003245 retryCnt++;
3246 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
3247 if (retryCnt >= DRXK_MAX_RETRIES)
3248 return -1;
3249 /* Write sub-command */
3250 switch (cmd) {
3251 /* All commands using sub-cmd */
3252 case OFDM_SC_RA_RAM_CMD_PROC_START:
3253 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3254 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003255 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003256 write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003257 break;
3258 default:
3259 /* Do nothing */
3260 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003261 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003262
3263 /* Write needed parameters and the command */
3264 switch (cmd) {
3265 /* All commands using 5 parameters */
3266 /* All commands using 4 parameters */
3267 /* All commands using 3 parameters */
3268 /* All commands using 2 parameters */
3269 case OFDM_SC_RA_RAM_CMD_PROC_START:
3270 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3271 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003272 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003273 write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003274 /* All commands using 1 parameters */
3275 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3276 case OFDM_SC_RA_RAM_CMD_USER_IO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003277 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003278 write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003279 /* All commands using 0 parameters */
3280 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3281 case OFDM_SC_RA_RAM_CMD_NULL:
3282 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003283 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003284 break;
3285 default:
3286 /* Unknown command */
3287 return -EINVAL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003288 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003289
3290 /* Wait until sc is ready processing command */
3291 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003292 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003293 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003294 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003295 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003296 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003297 if (retryCnt >= DRXK_MAX_RETRIES)
3298 return -1;
3299
3300 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003301 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003302 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003303 /* illegal command */
3304 return -EINVAL;
3305 }
3306
3307 /* Retreive results parameters from SC */
3308 switch (cmd) {
3309 /* All commands yielding 5 results */
3310 /* All commands yielding 4 results */
3311 /* All commands yielding 3 results */
3312 /* All commands yielding 2 results */
3313 /* All commands yielding 1 result */
3314 case OFDM_SC_RA_RAM_CMD_USER_IO:
3315 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003316 status =
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003317 read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003318 /* All commands yielding 0 results */
3319 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3320 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3321 case OFDM_SC_RA_RAM_CMD_PROC_START:
3322 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3323 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3324 case OFDM_SC_RA_RAM_CMD_NULL:
3325 break;
3326 default:
3327 /* Unknown command */
3328 return -EINVAL;
3329 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003330 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003331 return status;
3332}
3333
Oliver Endrissebc7de22011-07-03 13:49:44 -03003334static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003335{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003336 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003337 int status;
3338
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003339 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003340 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003341 status = CtrlPowerMode(state, &powerMode);
3342 if (status < 0)
3343 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003344 } while (0);
3345 return status;
3346}
3347
Oliver Endrissebc7de22011-07-03 13:49:44 -03003348static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003349{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003350 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003351
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003352 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003353 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003354 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003355 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003356 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003357
3358 return status;
3359}
3360
3361#define DEFAULT_FR_THRES_8K 4000
3362static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3363{
3364
3365 int status;
3366
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003367 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003368 if (*enabled == true) {
3369 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003370 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003371 DEFAULT_FR_THRES_8K);
3372 } else {
3373 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003374 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003375 }
3376
3377 return status;
3378}
3379
3380static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3381 struct DRXKCfgDvbtEchoThres_t *echoThres)
3382{
3383 u16 data = 0;
3384 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003385
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003386 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003387 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003388 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003389 if (status < 0)
3390 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003391
Oliver Endrissebc7de22011-07-03 13:49:44 -03003392 switch (echoThres->fftMode) {
3393 case DRX_FFTMODE_2K:
3394 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3395 data |=
3396 ((echoThres->threshold <<
3397 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3398 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3399 break;
3400 case DRX_FFTMODE_8K:
3401 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3402 data |=
3403 ((echoThres->threshold <<
3404 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3405 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3406 break;
3407 default:
3408 return -1;
3409 break;
3410 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003411
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003412 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003413 if (status < 0)
3414 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003415 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003416
Oliver Endrissebc7de22011-07-03 13:49:44 -03003417 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003418}
3419
3420static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003421 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003422{
3423 int status;
3424
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003425 dprintk(1, "\n");
3426
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003427 switch (*speed) {
3428 case DRXK_DVBT_SQI_SPEED_FAST:
3429 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3430 case DRXK_DVBT_SQI_SPEED_SLOW:
3431 break;
3432 default:
3433 return -EINVAL;
3434 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003435 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003436 (u16) *speed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003437 return status;
3438}
3439
3440/*============================================================================*/
3441
3442/**
3443* \brief Activate DVBT specific presets
3444* \param demod instance of demodulator.
3445* \return DRXStatus_t.
3446*
3447* Called in DVBTSetStandard
3448*
3449*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003450static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003451{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003452 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003453
Oliver Endrissebc7de22011-07-03 13:49:44 -03003454 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3455 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003456
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003457 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003458 do {
3459 bool setincenable = false;
3460 bool setfrenable = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003461 status = DVBTCtrlSetIncEnable(state, &setincenable);
3462 if (status < 0)
3463 break;
3464 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3465 if (status < 0)
3466 break;
3467 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3468 if (status < 0)
3469 break;
3470 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3471 if (status < 0)
3472 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003473 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003474 if (status < 0)
3475 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003476 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003477
Oliver Endrissebc7de22011-07-03 13:49:44 -03003478 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003479}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003480
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003481/*============================================================================*/
3482
3483/**
3484* \brief Initialize channelswitch-independent settings for DVBT.
3485* \param demod instance of demodulator.
3486* \return DRXStatus_t.
3487*
3488* For ROM code channel filter taps are loaded from the bootloader. For microcode
3489* the DVB-T taps from the drxk_filters.h are used.
3490*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003491static int SetDVBTStandard(struct drxk_state *state,
3492 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003493{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003494 u16 cmdResult = 0;
3495 u16 data = 0;
3496 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003497
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003498 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003499
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003500 PowerUpDVBT(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003501 do {
3502 /* added antenna switch */
3503 SwitchAntennaToDVBT(state);
3504 /* send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003505 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
3506 if (status < 0)
3507 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003508
3509 /* send OFDM setenv command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003510 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3511 if (status < 0)
3512 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003513
3514 /* reset datapath for OFDM, processors first */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003515 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003516 if (status < 0)
3517 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003518 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003519 if (status < 0)
3520 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003521 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003522 if (status < 0)
3523 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003524
3525 /* IQM setup */
3526 /* synchronize on ofdstate->m_festart */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003527 status = write16(state, IQM_AF_UPD_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003528 if (status < 0)
3529 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003530 /* window size for clipping ADC detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003531 status = write16(state, IQM_AF_CLP_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003532 if (status < 0)
3533 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003534 /* window size for for sense pre-SAW detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003535 status = write16(state, IQM_AF_SNS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003536 if (status < 0)
3537 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003538 /* sense threshold for sense pre-SAW detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003539 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003540 if (status < 0)
3541 break;
3542 status = SetIqmAf(state, true);
3543 if (status < 0)
3544 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003545
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003546 status = write16(state, IQM_AF_AGC_RF__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003547 if (status < 0)
3548 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003549
3550 /* Impulse noise cruncher setup */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003551 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003552 if (status < 0)
3553 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003554 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003555 if (status < 0)
3556 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003557 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003558 if (status < 0)
3559 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003560
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003561 status = write16(state, IQM_RC_STRETCH__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003562 if (status < 0)
3563 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003564 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003565 if (status < 0)
3566 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003567 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003568 if (status < 0)
3569 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003570 status = write16(state, IQM_CF_SCALE__A, 1600);
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_SCALE_SH__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003574 if (status < 0)
3575 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003576
3577 /* virtual clipping threshold for clipping ADC detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003578 status = write16(state, IQM_AF_CLP_TH__A, 448);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003579 if (status < 0)
3580 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003581 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003582 if (status < 0)
3583 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003584
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003585 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3586 if (status < 0)
3587 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003588
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003589 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003590 if (status < 0)
3591 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003592 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003593 if (status < 0)
3594 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003595 /* enable power measurement interrupt */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003596 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003597 if (status < 0)
3598 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003599 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003600 if (status < 0)
3601 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003602
3603 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003604 status = ADCSynchronization(state);
3605 if (status < 0)
3606 break;
3607 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3608 if (status < 0)
3609 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003610
3611 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003612 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003613 if (status < 0)
3614 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003615
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003616 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3617 if (status < 0)
3618 break;
3619 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3620 if (status < 0)
3621 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003622
3623 /* Set Noise Estimation notch width and enable DC fix */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003624 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003625 if (status < 0)
3626 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003627 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003628 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003629 if (status < 0)
3630 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003631
3632 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003633 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003634 if (status < 0)
3635 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003636
Oliver Endrissebc7de22011-07-03 13:49:44 -03003637 if (!state->m_DRXK_A3_ROM_CODE) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003638 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003639 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003640 if (status < 0)
3641 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003642 }
3643
3644 /* OFDM_SC setup */
3645#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003646 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003647 if (status < 0)
3648 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003649 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003650 if (status < 0)
3651 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003652#endif
3653
3654 /* FEC setup */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003655 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003656 if (status < 0)
3657 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003658
3659
3660#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003661 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003662 if (status < 0)
3663 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003664#else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003665 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003666 if (status < 0)
3667 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003668#endif
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003669 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003670 if (status < 0)
3671 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003672
3673 /* Setup MPEG bus */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003674 status = MPEGTSDtoSetup(state, OM_DVBT);
3675 if (status < 0)
3676 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003677 /* Set DVBT Presets */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003678 status = DVBTActivatePresets(state);
3679 if (status < 0)
3680 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003681
3682 } while (0);
3683
Oliver Endrissebc7de22011-07-03 13:49:44 -03003684 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003685 printk(KERN_ERR "drxk: %s status - %08x\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003686
3687 return status;
3688}
3689
3690/*============================================================================*/
3691/**
3692* \brief Start dvbt demodulating for channel.
3693* \param demod instance of demodulator.
3694* \return DRXStatus_t.
3695*/
3696static int DVBTStart(struct drxk_state *state)
3697{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003698 u16 param1;
3699 int status;
3700 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003701
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003702 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003703 /* Start correct processes to get in lock */
3704 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
3705 do {
3706 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003707 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3708 if (status < 0)
3709 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003710 /* Start FEC OC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003711 status = MPEGTSStart(state);
3712 if (status < 0)
3713 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003714 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003715 if (status < 0)
3716 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003717 } while (0);
3718 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003719}
3720
3721
3722/*============================================================================*/
3723
3724/**
3725* \brief Set up dvbt demodulator for channel.
3726* \param demod instance of demodulator.
3727* \return DRXStatus_t.
3728* // original DVBTSetChannel()
3729*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003730static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3731 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003732{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003733 u16 cmdResult = 0;
3734 u16 transmissionParams = 0;
3735 u16 operationMode = 0;
3736 u32 iqmRcRateOfs = 0;
3737 u32 bandwidth = 0;
3738 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003739 int status;
3740
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003741 dprintk(1, "\n");
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003742 /* printk(KERN_DEBUG "drxk: %s IF =%d, TFO = %d\n", __func__, IntermediateFreqkHz, tunerFreqOffset); */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003743 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003744 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3745 if (status < 0)
3746 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003747
3748 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003749 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003750 if (status < 0)
3751 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003752
3753 /* Stop processors */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003754 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003755 if (status < 0)
3756 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003757 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003758 if (status < 0)
3759 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003760
3761 /* Mandatory fix, always stop CP, required to set spl offset back to
3762 hardware default (is set to 0 by ucode during pilot detection */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003763 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_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 /*== Write channel settings to device =====================================*/
3768
3769 /* mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003770 switch (state->param.u.ofdm.transmission_mode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003771 case TRANSMISSION_MODE_AUTO:
3772 default:
3773 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3774 /* fall through , try first guess DRX_FFTMODE_8K */
3775 case TRANSMISSION_MODE_8K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003776 transmissionParams |=
3777 OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003778 break;
3779 case TRANSMISSION_MODE_2K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003780 transmissionParams |=
3781 OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003782 break;
3783 }
3784
3785 /* guard */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003786 switch (state->param.u.ofdm.guard_interval) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003787 default:
3788 case GUARD_INTERVAL_AUTO:
3789 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3790 /* fall through , try first guess DRX_GUARD_1DIV4 */
3791 case GUARD_INTERVAL_1_4:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003792 transmissionParams |=
3793 OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003794 break;
3795 case GUARD_INTERVAL_1_32:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003796 transmissionParams |=
3797 OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003798 break;
3799 case GUARD_INTERVAL_1_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003800 transmissionParams |=
3801 OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003802 break;
3803 case GUARD_INTERVAL_1_8:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003804 transmissionParams |=
3805 OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003806 break;
3807 }
3808
3809 /* hierarchy */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003810 switch (state->param.u.ofdm.hierarchy_information) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003811 case HIERARCHY_AUTO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003812 case HIERARCHY_NONE:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003813 default:
3814 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3815 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003816 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3817 /* break; */
3818 case HIERARCHY_1:
3819 transmissionParams |=
3820 OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003821 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003822 case HIERARCHY_2:
3823 transmissionParams |=
3824 OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003825 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003826 case HIERARCHY_4:
3827 transmissionParams |=
3828 OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003829 break;
3830 }
3831
3832
3833 /* constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003834 switch (state->param.u.ofdm.constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003835 case QAM_AUTO:
3836 default:
3837 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3838 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3839 case QAM_64:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003840 transmissionParams |=
3841 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003842 break;
3843 case QPSK:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003844 transmissionParams |=
3845 OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003846 break;
3847 case QAM_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003848 transmissionParams |=
3849 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003850 break;
3851 }
3852#if 0
Oliver Endrissebc7de22011-07-03 13:49:44 -03003853 /* No hierachical channels support in BDA */
3854 /* Priority (only for hierarchical channels) */
3855 switch (channel->priority) {
3856 case DRX_PRIORITY_LOW:
3857 transmissionParams |=
3858 OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3859 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3860 OFDM_EC_SB_PRIOR_LO);
3861 break;
3862 case DRX_PRIORITY_HIGH:
3863 transmissionParams |=
3864 OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3865 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3866 OFDM_EC_SB_PRIOR_HI));
3867 break;
3868 case DRX_PRIORITY_UNKNOWN: /* fall through */
3869 default:
3870 return DRX_STS_INVALID_ARG;
3871 break;
3872 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003873#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03003874 /* Set Priorty high */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003875 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003876 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003877 if (status < 0)
3878 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003879#endif
3880
3881 /* coderate */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003882 switch (state->param.u.ofdm.code_rate_HP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003883 case FEC_AUTO:
3884 default:
3885 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3886 /* fall through , try first guess DRX_CODERATE_2DIV3 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003887 case FEC_2_3:
3888 transmissionParams |=
3889 OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003890 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003891 case FEC_1_2:
3892 transmissionParams |=
3893 OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003894 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003895 case FEC_3_4:
3896 transmissionParams |=
3897 OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003898 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003899 case FEC_5_6:
3900 transmissionParams |=
3901 OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003902 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003903 case FEC_7_8:
3904 transmissionParams |=
3905 OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003906 break;
3907 }
3908
3909 /* SAW filter selection: normaly not necesarry, but if wanted
3910 the application can select a SAW filter via the driver by using UIOs */
3911 /* First determine real bandwidth (Hz) */
3912 /* Also set delay for impulse noise cruncher */
3913 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3914 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3915 functions */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003916 switch (state->param.u.ofdm.bandwidth) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003917 case BANDWIDTH_AUTO:
3918 case BANDWIDTH_8_MHZ:
3919 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003920 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003921 if (status < 0)
3922 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003923 /* cochannel protection for PAL 8 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003924 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003925 if (status < 0)
3926 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003927 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003928 if (status < 0)
3929 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003930 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_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_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003934 if (status < 0)
3935 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003936 break;
3937 case BANDWIDTH_7_MHZ:
3938 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003939 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003940 if (status < 0)
3941 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003942 /* cochannel protection for PAL 7 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003943 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003944 if (status < 0)
3945 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003946 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003947 if (status < 0)
3948 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003949 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
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_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003953 if (status < 0)
3954 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003955 break;
3956 case BANDWIDTH_6_MHZ:
3957 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003958 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003959 if (status < 0)
3960 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003961 /* cochannel protection for NTSC 6 MHz */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003962 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003963 if (status < 0)
3964 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003965 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003966 if (status < 0)
3967 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003968 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
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_2K_PER_RIGHT__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003972 if (status < 0)
3973 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003974 break;
Mauro Carvalho Chehabe16cede2011-07-03 18:18:14 -03003975 default:
3976 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003977 }
3978
Oliver Endrissebc7de22011-07-03 13:49:44 -03003979 if (iqmRcRateOfs == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003980 /* Now compute IQM_RC_RATE_OFS
3981 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3982 =>
3983 ((SysFreq / BandWidth) * (2^21)) - (2^23)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003984 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003985 /* (SysFreq / BandWidth) * (2^28) */
3986 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
3987 => assert(MAX(sysClk) < 16*MIN(bandwidth))
3988 => assert(109714272 > 48000000) = true so Frac 28 can be used */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003989 iqmRcRateOfs = Frac28a((u32)
3990 ((state->m_sysClockFreq *
3991 1000) / 3), bandwidth);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003992 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
3993 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003994 iqmRcRateOfs += 0x80L;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003995 iqmRcRateOfs = iqmRcRateOfs >> 7;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003996 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003997 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003998 }
3999
Oliver Endrissebc7de22011-07-03 13:49:44 -03004000 iqmRcRateOfs &=
4001 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4002 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004003 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004004 if (status < 0)
4005 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004006
4007 /* Bandwidth setting done */
4008
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004009#if 0
4010 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4011 if (status < 0)
4012 break;
4013#endif
4014 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4015 if (status < 0)
4016 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004017
4018 /*== Start SC, write channel settings to SC ===============================*/
4019
4020 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004021 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004022 if (status < 0)
4023 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004024
4025 /* Enable SC after setting all other parameters */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004026 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004027 if (status < 0)
4028 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004029 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004030 if (status < 0)
4031 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004032
4033
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004034 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4035 if (status < 0)
4036 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004037
4038 /* Write SC parameter registers, set all AUTO flags in operation mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004039 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4040 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4041 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4042 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4043 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4044 status =
4045 DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4046 0, transmissionParams, param1, 0, 0, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004047 if (!state->m_DRXK_A3_ROM_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004048 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4049 if (status < 0)
4050 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004051
Oliver Endrissebc7de22011-07-03 13:49:44 -03004052 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004053
4054 return status;
4055}
4056
4057
4058/*============================================================================*/
4059
4060/**
4061* \brief Retreive lock status .
4062* \param demod Pointer to demodulator instance.
4063* \param lockStat Pointer to lock status structure.
4064* \return DRXStatus_t.
4065*
4066*/
4067static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4068{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004069 int status;
4070 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4071 OFDM_SC_RA_RAM_LOCK_FEC__M);
4072 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4073 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004074
Oliver Endrissebc7de22011-07-03 13:49:44 -03004075 u16 ScRaRamLock = 0;
4076 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004077
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004078 dprintk(1, "\n");
4079
Oliver Endrissebc7de22011-07-03 13:49:44 -03004080 /* driver 0.9.0 */
4081 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004082 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004083 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP) {
4084 /* SC not active; return DRX_NOT_LOCKED */
4085 *pLockStatus = NOT_LOCKED;
4086 return status;
4087 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004088
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004089 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004090
Oliver Endrissebc7de22011-07-03 13:49:44 -03004091 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4092 *pLockStatus = MPEG_LOCK;
4093 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4094 *pLockStatus = FEC_LOCK;
4095 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4096 *pLockStatus = DEMOD_LOCK;
4097 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4098 *pLockStatus = NEVER_LOCK;
4099 else
4100 *pLockStatus = NOT_LOCKED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004101
Oliver Endrissebc7de22011-07-03 13:49:44 -03004102 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004103}
4104
Oliver Endrissebc7de22011-07-03 13:49:44 -03004105static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004106{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004107 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
4108 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004109
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004110 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004111 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004112 status = CtrlPowerMode(state, &powerMode);
4113 if (status < 0)
4114 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004115
Oliver Endrissebc7de22011-07-03 13:49:44 -03004116 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004117
Oliver Endrissebc7de22011-07-03 13:49:44 -03004118 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004119}
4120
4121
Oliver Endrissebc7de22011-07-03 13:49:44 -03004122/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004123static int PowerDownQAM(struct drxk_state *state)
4124{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004125 u16 data = 0;
4126 u16 cmdResult;
4127 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004128
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004129 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004130 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004131 status = read16(state, SCU_COMM_EXEC__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004132 if (status < 0)
4133 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004134 if (data == SCU_COMM_EXEC_ACTIVE) {
4135 /*
4136 STOP demodulator
4137 QAM and HW blocks
4138 */
4139 /* stop all comstate->m_exec */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004140 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004141 if (status < 0)
4142 break;
4143 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
4144 if (status < 0)
4145 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004146 }
4147 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004148 status = SetIqmAf(state, false);
4149 if (status < 0)
4150 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004151 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004152
Oliver Endrissebc7de22011-07-03 13:49:44 -03004153 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004154}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004155
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004156/*============================================================================*/
4157
4158/**
4159* \brief Setup of the QAM Measurement intervals for signal quality
4160* \param demod instance of demod.
4161* \param constellation current constellation.
4162* \return DRXStatus_t.
4163*
4164* NOTE:
4165* Take into account that for certain settings the errorcounters can overflow.
4166* The implementation does not check this.
4167*
4168*/
4169static int SetQAMMeasurement(struct drxk_state *state,
4170 enum EDrxkConstellation constellation,
4171 u32 symbolRate)
4172{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004173 u32 fecBitsDesired = 0; /* BER accounting period */
4174 u32 fecRsPeriodTotal = 0; /* Total period */
4175 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4176 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004177 int status = 0;
4178
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004179 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004180
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004181 fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004182 do {
4183
4184 /* fecBitsDesired = symbolRate [kHz] *
4185 FrameLenght [ms] *
4186 (constellation + 1) *
4187 SyncLoss (== 1) *
4188 ViterbiLoss (==1)
Oliver Endrissebc7de22011-07-03 13:49:44 -03004189 */
4190 switch (constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004191 case DRX_CONSTELLATION_QAM16:
4192 fecBitsDesired = 4 * symbolRate;
4193 break;
4194 case DRX_CONSTELLATION_QAM32:
4195 fecBitsDesired = 5 * symbolRate;
4196 break;
4197 case DRX_CONSTELLATION_QAM64:
4198 fecBitsDesired = 6 * symbolRate;
4199 break;
4200 case DRX_CONSTELLATION_QAM128:
4201 fecBitsDesired = 7 * symbolRate;
4202 break;
4203 case DRX_CONSTELLATION_QAM256:
4204 fecBitsDesired = 8 * symbolRate;
4205 break;
4206 default:
4207 status = -EINVAL;
4208 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004209 status = status;
4210 if (status < 0)
4211 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004212
Oliver Endrissebc7de22011-07-03 13:49:44 -03004213 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4214 fecBitsDesired *= 500; /* meas. period [ms] */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004215
4216 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4217 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004218 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004219
4220 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4221 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4222 if (fecRsPrescale == 0) {
4223 /* Divide by zero (though impossible) */
4224 status = -1;
4225 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004226 status = status;
4227 if (status < 0)
4228 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004229 fecRsPeriod =
4230 ((u16) fecRsPeriodTotal +
4231 (fecRsPrescale >> 1)) / fecRsPrescale;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004232
4233 /* write corresponding registers */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004234 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004235 if (status < 0)
4236 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004237 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004238 if (status < 0)
4239 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004240 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004241 if (status < 0)
4242 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004243
4244 } while (0);
4245
Oliver Endrissebc7de22011-07-03 13:49:44 -03004246 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03004247 printk(KERN_ERR "drxk: %s: status - %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004248
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004249 return status;
4250}
4251
Oliver Endrissebc7de22011-07-03 13:49:44 -03004252static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004253{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004254 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004255
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004256 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004257 do {
4258 /* QAM Equalizer Setup */
4259 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004260 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004261 if (status < 0)
4262 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004263 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004264 if (status < 0)
4265 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004266 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__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_RAD3__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_RAD4__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_RAD5__A, 13517);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004276 if (status < 0)
4277 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004278 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004279 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004280 if (status < 0)
4281 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004282 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004283 if (status < 0)
4284 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004285 status = write16(state, QAM_DQ_QUAL_FUN2__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_FUN3__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_FUN4__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_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004295 if (status < 0)
4296 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004297
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004298 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004299 if (status < 0)
4300 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004301 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004302 if (status < 0)
4303 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004304 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004305 if (status < 0)
4306 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004307
Oliver Endrissebc7de22011-07-03 13:49:44 -03004308 /* QAM Slicer Settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004309 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004310 if (status < 0)
4311 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004312
Oliver Endrissebc7de22011-07-03 13:49:44 -03004313 /* QAM Loop Controller Coeficients */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004314 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004315 if (status < 0)
4316 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004317 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004318 if (status < 0)
4319 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004320 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004321 if (status < 0)
4322 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004323 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004324 if (status < 0)
4325 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004326 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004327 if (status < 0)
4328 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004329 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004330 if (status < 0)
4331 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004332 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
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_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004336 if (status < 0)
4337 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004338
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004339 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004340 if (status < 0)
4341 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004342 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004343 if (status < 0)
4344 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004345 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004346 if (status < 0)
4347 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004348 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004349 if (status < 0)
4350 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004351 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004352 if (status < 0)
4353 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004354 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004355 if (status < 0)
4356 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004357 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004358 if (status < 0)
4359 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004360 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
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_COARSE__A, 32);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004364 if (status < 0)
4365 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004366 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004367 if (status < 0)
4368 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004369 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
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_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004373 if (status < 0)
4374 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004375
4376
Oliver Endrissebc7de22011-07-03 13:49:44 -03004377 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004378
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004379 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004380 if (status < 0)
4381 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004382 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004383 if (status < 0)
4384 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004385 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
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_PTH__A, 120);
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_QTH__A, 230);
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_MTH__A, 105);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004395 if (status < 0)
4396 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004397
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004398 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004399 if (status < 0)
4400 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004401 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004402 if (status < 0)
4403 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004404 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004405 if (status < 0)
4406 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004407
4408
Oliver Endrissebc7de22011-07-03 13:49:44 -03004409 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004410
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004411 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004412 if (status < 0)
4413 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004414 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004415 if (status < 0)
4416 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004417 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004418 if (status < 0)
4419 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004420 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
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_OFFSET3__A, (u16) -24);
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_OFFSET4__A, (u16) -65);
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_OFFSET5__A, (u16) -127);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004430 if (status < 0)
4431 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004432 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004433
Oliver Endrissebc7de22011-07-03 13:49:44 -03004434 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004435}
4436
4437/*============================================================================*/
4438
4439/**
4440* \brief QAM32 specific setup
4441* \param demod instance of demod.
4442* \return DRXStatus_t.
4443*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004444static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004445{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004446 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004447
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004448 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004449 do {
4450 /* QAM Equalizer Setup */
4451 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004452 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004453 if (status < 0)
4454 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004455 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004456 if (status < 0)
4457 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004458 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__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_RAD3__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_RAD4__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_RAD5__A, 6707);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004468 if (status < 0)
4469 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004470
Oliver Endrissebc7de22011-07-03 13:49:44 -03004471 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004472 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004473 if (status < 0)
4474 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004475 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004476 if (status < 0)
4477 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004478 status = write16(state, QAM_DQ_QUAL_FUN2__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_FUN3__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_FUN4__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_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004488 if (status < 0)
4489 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004490
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004491 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004492 if (status < 0)
4493 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004494 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004495 if (status < 0)
4496 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004497 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004498 if (status < 0)
4499 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004500
Oliver Endrissebc7de22011-07-03 13:49:44 -03004501 /* QAM Slicer Settings */
4502
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004503 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004504 if (status < 0)
4505 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004506
4507
Oliver Endrissebc7de22011-07-03 13:49:44 -03004508 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004509
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004510 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004511 if (status < 0)
4512 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004513 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004514 if (status < 0)
4515 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004516 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004517 if (status < 0)
4518 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004519 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004520 if (status < 0)
4521 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004522 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004523 if (status < 0)
4524 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004525 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004526 if (status < 0)
4527 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004528 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
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_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004532 if (status < 0)
4533 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004534
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004535 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004536 if (status < 0)
4537 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004538 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004539 if (status < 0)
4540 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004541 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004542 if (status < 0)
4543 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004544 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004545 if (status < 0)
4546 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004547 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004548 if (status < 0)
4549 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004550 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004551 if (status < 0)
4552 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004553 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004554 if (status < 0)
4555 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004556 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004557 if (status < 0)
4558 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004559 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__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_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004563 if (status < 0)
4564 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004565 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
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_COARSE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004569 if (status < 0)
4570 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004571
4572
Oliver Endrissebc7de22011-07-03 13:49:44 -03004573 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004574
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004575 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004576 if (status < 0)
4577 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004578 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004579 if (status < 0)
4580 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004581 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
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_PTH__A, 100);
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_QTH__A, 170);
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_MTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004591 if (status < 0)
4592 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004593
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004594 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004595 if (status < 0)
4596 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004597 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004598 if (status < 0)
4599 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004600 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004601 if (status < 0)
4602 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004603
4604
Oliver Endrissebc7de22011-07-03 13:49:44 -03004605 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004606
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004607 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004608 if (status < 0)
4609 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004610 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004611 if (status < 0)
4612 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004613 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004614 if (status < 0)
4615 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004616 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
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_OFFSET3__A, (u16) -26);
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_OFFSET4__A, (u16) -56);
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_OFFSET5__A, (u16) -86);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004626 if (status < 0)
4627 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004628 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004629
Oliver Endrissebc7de22011-07-03 13:49:44 -03004630 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004631}
4632
4633/*============================================================================*/
4634
4635/**
4636* \brief QAM64 specific setup
4637* \param demod instance of demod.
4638* \return DRXStatus_t.
4639*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004640static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004641{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004642 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004643
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004644 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004645 do {
4646 /* QAM Equalizer Setup */
4647 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004648 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004649 if (status < 0)
4650 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004651 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004652 if (status < 0)
4653 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004654 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
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_RAD3__A, 13809);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004658 if (status < 0)
4659 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004660 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
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_RAD5__A, 15609);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004664 if (status < 0)
4665 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004666
Oliver Endrissebc7de22011-07-03 13:49:44 -03004667 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004668 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004669 if (status < 0)
4670 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004671 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004672 if (status < 0)
4673 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004674 status = write16(state, QAM_DQ_QUAL_FUN2__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_FUN3__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_FUN4__A, 3);
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_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004684 if (status < 0)
4685 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004686
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004687 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004688 if (status < 0)
4689 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004690 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004691 if (status < 0)
4692 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004693 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004694 if (status < 0)
4695 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004696
4697 /* QAM Slicer Settings */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004698 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004699 if (status < 0)
4700 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004701
4702
Oliver Endrissebc7de22011-07-03 13:49:44 -03004703 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004704
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004705 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004706 if (status < 0)
4707 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004708 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004709 if (status < 0)
4710 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004711 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004712 if (status < 0)
4713 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004714 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004715 if (status < 0)
4716 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004717 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004718 if (status < 0)
4719 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004720 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004721 if (status < 0)
4722 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004723 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
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_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004727 if (status < 0)
4728 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004729
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004730 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004731 if (status < 0)
4732 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004733 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004734 if (status < 0)
4735 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004736 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004737 if (status < 0)
4738 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004739 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004740 if (status < 0)
4741 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004742 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004743 if (status < 0)
4744 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004745 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004746 if (status < 0)
4747 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004748 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004749 if (status < 0)
4750 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004751 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
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_COARSE__A, 48);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004755 if (status < 0)
4756 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004757 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004758 if (status < 0)
4759 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004760 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
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_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004764 if (status < 0)
4765 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004766
4767
Oliver Endrissebc7de22011-07-03 13:49:44 -03004768 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004769
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004770 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004771 if (status < 0)
4772 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004773 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004774 if (status < 0)
4775 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004776 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
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_PTH__A, 110);
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_QTH__A, 200);
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_MTH__A, 95);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004786 if (status < 0)
4787 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004788
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004789 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004790 if (status < 0)
4791 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004792 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004793 if (status < 0)
4794 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004795 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004796 if (status < 0)
4797 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004798
4799
Oliver Endrissebc7de22011-07-03 13:49:44 -03004800 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004801
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004802 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004803 if (status < 0)
4804 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004805 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004806 if (status < 0)
4807 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004808 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004809 if (status < 0)
4810 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004811 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
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_OFFSET3__A, (u16) -15);
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_OFFSET4__A, (u16) -45);
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_OFFSET5__A, (u16) -80);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004821 if (status < 0)
4822 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004823 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004824
Oliver Endrissebc7de22011-07-03 13:49:44 -03004825 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004826}
4827
4828/*============================================================================*/
4829
4830/**
4831* \brief QAM128 specific setup
4832* \param demod: instance of demod.
4833* \return DRXStatus_t.
4834*/
4835static int SetQAM128(struct drxk_state *state)
4836{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004837 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004838
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004839 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004840 do {
4841 /* QAM Equalizer Setup */
4842 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004843 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004844 if (status < 0)
4845 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004846 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004847 if (status < 0)
4848 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004849 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
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_RAD3__A, 6409);
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_RAD4__A, 6656);
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_RAD5__A, 7238);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004859 if (status < 0)
4860 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004861
Oliver Endrissebc7de22011-07-03 13:49:44 -03004862 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004863 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004864 if (status < 0)
4865 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004866 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004867 if (status < 0)
4868 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004869 status = write16(state, QAM_DQ_QUAL_FUN2__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_FUN3__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_FUN4__A, 5);
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_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004879 if (status < 0)
4880 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004881
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004882 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004883 if (status < 0)
4884 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004885 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004886 if (status < 0)
4887 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004888 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004889 if (status < 0)
4890 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004891
4892
Oliver Endrissebc7de22011-07-03 13:49:44 -03004893 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004894
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004895 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004896 if (status < 0)
4897 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004898
4899
Oliver Endrissebc7de22011-07-03 13:49:44 -03004900 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004901
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004902 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004903 if (status < 0)
4904 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004905 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004906 if (status < 0)
4907 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004908 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004909 if (status < 0)
4910 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004911 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004912 if (status < 0)
4913 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004914 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004915 if (status < 0)
4916 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004917 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004918 if (status < 0)
4919 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004920 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
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_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004924 if (status < 0)
4925 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004926
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004927 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004928 if (status < 0)
4929 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004930 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004931 if (status < 0)
4932 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004933 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004934 if (status < 0)
4935 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004936 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004937 if (status < 0)
4938 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004939 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004940 if (status < 0)
4941 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004942 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004943 if (status < 0)
4944 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004945 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004946 if (status < 0)
4947 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004948 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
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_COARSE__A, 64);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004952 if (status < 0)
4953 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004954 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004955 if (status < 0)
4956 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004957 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
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_COARSE__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004961 if (status < 0)
4962 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004963
4964
Oliver Endrissebc7de22011-07-03 13:49:44 -03004965 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004966
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004967 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004968 if (status < 0)
4969 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004970 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004971 if (status < 0)
4972 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004973 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
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_PTH__A, 100);
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_QTH__A, 140);
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_MTH__A, 100);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004983 if (status < 0)
4984 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004985
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004986 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004987 if (status < 0)
4988 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004989 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004990 if (status < 0)
4991 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004992
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004993 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004994 if (status < 0)
4995 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004996
Oliver Endrissebc7de22011-07-03 13:49:44 -03004997 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004998
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004999 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005000 if (status < 0)
5001 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005002 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005003 if (status < 0)
5004 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005005 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005006 if (status < 0)
5007 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005008 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
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_OFFSET3__A, (u16) -1);
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_OFFSET4__A, (u16) -12);
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_OFFSET5__A, (u16) -23);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005018 if (status < 0)
5019 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005020 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005021
Oliver Endrissebc7de22011-07-03 13:49:44 -03005022 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005023}
5024
5025/*============================================================================*/
5026
5027/**
5028* \brief QAM256 specific setup
5029* \param demod: instance of demod.
5030* \return DRXStatus_t.
5031*/
5032static int SetQAM256(struct drxk_state *state)
5033{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005034 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005035
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005036 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005037 do {
5038 /* QAM Equalizer Setup */
5039 /* Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005040 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005041 if (status < 0)
5042 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005043 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005044 if (status < 0)
5045 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005046 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
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_RAD3__A, 12931);
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_RAD4__A, 13629);
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_RAD5__A, 15385);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005056 if (status < 0)
5057 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005058
Oliver Endrissebc7de22011-07-03 13:49:44 -03005059 /* Decision Feedback Equalizer */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005060 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005061 if (status < 0)
5062 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005063 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005064 if (status < 0)
5065 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005066 status = write16(state, QAM_DQ_QUAL_FUN2__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_FUN3__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_FUN4__A, 6);
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_FUN5__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005076 if (status < 0)
5077 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005078
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005079 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005080 if (status < 0)
5081 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005082 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005083 if (status < 0)
5084 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005085 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005086 if (status < 0)
5087 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005088
Oliver Endrissebc7de22011-07-03 13:49:44 -03005089 /* QAM Slicer Settings */
5090
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005091 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005092 if (status < 0)
5093 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005094
5095
Oliver Endrissebc7de22011-07-03 13:49:44 -03005096 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005097
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005098 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005099 if (status < 0)
5100 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005101 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005102 if (status < 0)
5103 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005104 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005105 if (status < 0)
5106 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005107 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005108 if (status < 0)
5109 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005110 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005111 if (status < 0)
5112 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005113 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005114 if (status < 0)
5115 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005116 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
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_COARSE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005120 if (status < 0)
5121 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005122
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005123 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005124 if (status < 0)
5125 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005126 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005127 if (status < 0)
5128 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005129 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005130 if (status < 0)
5131 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005132 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005133 if (status < 0)
5134 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005135 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005136 if (status < 0)
5137 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005138 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005139 if (status < 0)
5140 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005141 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005142 if (status < 0)
5143 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005144 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
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_COARSE__A, 48);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005148 if (status < 0)
5149 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005150 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005151 if (status < 0)
5152 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005153 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
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_COARSE__A, 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005157 if (status < 0)
5158 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005159
5160
Oliver Endrissebc7de22011-07-03 13:49:44 -03005161 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005162
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005163 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005164 if (status < 0)
5165 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005166 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005167 if (status < 0)
5168 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005169 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
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_PTH__A, 100);
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_QTH__A, 150);
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_MTH__A, 110);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005179 if (status < 0)
5180 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005181
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005182 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005183 if (status < 0)
5184 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005185 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005186 if (status < 0)
5187 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005188 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005189 if (status < 0)
5190 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005191
5192
Oliver Endrissebc7de22011-07-03 13:49:44 -03005193 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005194
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005195 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005196 if (status < 0)
5197 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005198 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005199 if (status < 0)
5200 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005201 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005202 if (status < 0)
5203 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005204 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
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_OFFSET3__A, (u16) 7);
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_OFFSET4__A, (u16) 0);
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_OFFSET5__A, (u16) -8);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005214 if (status < 0)
5215 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005216 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005217
Oliver Endrissebc7de22011-07-03 13:49:44 -03005218 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005219}
5220
5221
5222/*============================================================================*/
5223/**
5224* \brief Reset QAM block.
5225* \param demod: instance of demod.
5226* \param channel: pointer to channel data.
5227* \return DRXStatus_t.
5228*/
5229static int QAMResetQAM(struct drxk_state *state)
5230{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005231 int status;
5232 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005233
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005234 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005235 do {
5236 /* Stop QAM comstate->m_exec */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005237 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005238 if (status < 0)
5239 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005240
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005241 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5242 if (status < 0)
5243 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005244 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005245
Oliver Endrissebc7de22011-07-03 13:49:44 -03005246 /* All done, all OK */
5247 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005248}
5249
5250/*============================================================================*/
5251
5252/**
5253* \brief Set QAM symbolrate.
5254* \param demod: instance of demod.
5255* \param channel: pointer to channel data.
5256* \return DRXStatus_t.
5257*/
5258static int QAMSetSymbolrate(struct drxk_state *state)
5259{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005260 u32 adcFrequency = 0;
5261 u32 symbFreq = 0;
5262 u32 iqmRcRate = 0;
5263 u16 ratesel = 0;
5264 u32 lcSymbRate = 0;
5265 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005266
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005267 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005268 do {
5269 /* Select & calculate correct IQM rate */
5270 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5271 ratesel = 0;
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005272 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005273 if (state->param.u.qam.symbol_rate <= 1188750)
5274 ratesel = 3;
5275 else if (state->param.u.qam.symbol_rate <= 2377500)
5276 ratesel = 2;
5277 else if (state->param.u.qam.symbol_rate <= 4755000)
5278 ratesel = 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005279 status = write16(state, IQM_FD_RATESEL__A, ratesel);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005280 if (status < 0)
5281 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005282
Oliver Endrissebc7de22011-07-03 13:49:44 -03005283 /*
5284 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5285 */
5286 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5287 if (symbFreq == 0) {
5288 /* Divide by zero */
5289 return -1;
5290 }
5291 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5292 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5293 (1 << 23);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005294 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005295 if (status < 0)
5296 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005297 state->m_iqmRcRate = iqmRcRate;
5298 /*
5299 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5300 */
5301 symbFreq = state->param.u.qam.symbol_rate;
5302 if (adcFrequency == 0) {
5303 /* Divide by zero */
5304 return -1;
5305 }
5306 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5307 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5308 16);
5309 if (lcSymbRate > 511)
5310 lcSymbRate = 511;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005311 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005312 if (status < 0)
5313 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005314 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005315
Oliver Endrissebc7de22011-07-03 13:49:44 -03005316 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005317}
5318
5319/*============================================================================*/
5320
5321/**
5322* \brief Get QAM lock status.
5323* \param demod: instance of demod.
5324* \param channel: pointer to channel data.
5325* \return DRXStatus_t.
5326*/
5327
5328static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5329{
5330 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005331 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005332
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005333 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005334 status =
5335 scu_command(state,
5336 SCU_RAM_COMMAND_STANDARD_QAM |
5337 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5338 Result);
5339 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005340 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005341
5342 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005343 /* 0x0000 NOT LOCKED */
5344 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005345 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005346 /* 0x4000 DEMOD LOCKED */
5347 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005348 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005349 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5350 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005351 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005352 /* 0xC000 NEVER LOCKED */
5353 /* (system will never be able to lock to the signal) */
5354 /* TODO: check this, intermediate & standard specific lock states are not
5355 taken into account here */
5356 *pLockStatus = NEVER_LOCK;
5357 }
5358 return status;
5359}
5360
5361#define QAM_MIRROR__M 0x03
5362#define QAM_MIRROR_NORMAL 0x00
5363#define QAM_MIRRORED 0x01
5364#define QAM_MIRROR_AUTO_ON 0x02
5365#define QAM_LOCKRANGE__M 0x10
5366#define QAM_LOCKRANGE_NORMAL 0x10
5367
Oliver Endrissebc7de22011-07-03 13:49:44 -03005368static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5369 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005370{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005371 int status = 0;
5372 u8 parameterLen;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005373 u16 setEnvParameters[5];
5374 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5375 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005376
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005377 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005378 do {
5379 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005380 STEP 1: reset demodulator
5381 resets FEC DI and FEC RS
5382 resets QAM block
5383 resets SCU variables
5384 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005385 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005386 if (status < 0)
5387 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005388 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005389 if (status < 0)
5390 break;
5391 status = QAMResetQAM(state);
5392 if (status < 0)
5393 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005394
5395 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005396 STEP 2: configure demodulator
5397 -set env
5398 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5399 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005400 status = QAMSetSymbolrate(state);
5401 if (status < 0)
5402 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005403
5404 /* Env parameters */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005405 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005406 if (state->m_OperationMode == OM_QAM_ITU_C)
Oliver Endrissebc7de22011-07-03 13:49:44 -03005407 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005408 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005409 /* check for LOCKRANGE Extented */
5410 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005411 parameterLen = 4;
5412
5413 /* Set params */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005414 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005415 case QAM_256:
5416 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5417 break;
5418 case QAM_AUTO:
5419 case QAM_64:
5420 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5421 break;
5422 case QAM_16:
5423 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5424 break;
5425 case QAM_32:
5426 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5427 break;
5428 case QAM_128:
5429 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5430 break;
5431 default:
5432 status = -EINVAL;
5433 break;
5434 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005435 status = status;
5436 if (status < 0)
5437 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005438 setParamParameters[0] = state->m_Constellation; /* constellation */
5439 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005440
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005441 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5442 if (status < 0)
5443 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005444
5445
5446 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5447 setup constellation independent registers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005448#if 0
5449 status = SetFrequency (channel, tunerFreqOffset));
5450 if (status < 0)
5451 break;
5452#endif
5453 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5454 if (status < 0)
5455 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005456
5457 /* Setup BER measurement */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005458 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5459 if (status < 0)
5460 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005461
5462 /* Reset default values */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005463 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005464 if (status < 0)
5465 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005466 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005467 if (status < 0)
5468 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005469
Oliver Endrissebc7de22011-07-03 13:49:44 -03005470 /* Reset default LC values */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005471 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005472 if (status < 0)
5473 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005474 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005475 if (status < 0)
5476 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005477 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
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_MODE__A, 7);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005481 if (status < 0)
5482 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005483
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005484 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005485 if (status < 0)
5486 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005487 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005488 if (status < 0)
5489 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005490 status = write16(state, QAM_LC_QUAL_TAB2__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_TAB3__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_TAB4__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005497 if (status < 0)
5498 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005499 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005500 if (status < 0)
5501 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005502 status = write16(state, QAM_LC_QUAL_TAB6__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_TAB8__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_TAB9__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_TAB10__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_TAB12__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_TAB15__A, 3);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005518 if (status < 0)
5519 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005520 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
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_TAB20__A, 4);
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_TAB25__A, 4);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005527 if (status < 0)
5528 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005529
Oliver Endrissebc7de22011-07-03 13:49:44 -03005530 /* Mirroring, QAM-block starting point not inverted */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005531 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005532 if (status < 0)
5533 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005534
Oliver Endrissebc7de22011-07-03 13:49:44 -03005535 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005536 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005537 if (status < 0)
5538 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005539
Oliver Endrissebc7de22011-07-03 13:49:44 -03005540 /* STEP 4: constellation specific setup */
5541 switch (state->param.u.qam.modulation) {
5542 case QAM_16:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005543 status = SetQAM16(state);
5544 if (status < 0)
5545 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005546 break;
5547 case QAM_32:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005548 status = SetQAM32(state);
5549 if (status < 0)
5550 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005551 break;
5552 case QAM_AUTO:
5553 case QAM_64:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005554 status = SetQAM64(state);
5555 if (status < 0)
5556 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005557 break;
5558 case QAM_128:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005559 status = SetQAM128(state);
5560 if (status < 0)
5561 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005562 break;
5563 case QAM_256:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005564 status = SetQAM256(state);
5565 if (status < 0)
5566 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005567 break;
5568 default:
5569 return -1;
5570 break;
5571 } /* switch */
5572 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005573 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005574 if (status < 0)
5575 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005576
5577
Oliver Endrissebc7de22011-07-03 13:49:44 -03005578 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5579 /* extAttr->currentChannel.constellation = channel->constellation; */
5580 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005581 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5582 if (status < 0)
5583 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005584
Oliver Endrissebc7de22011-07-03 13:49:44 -03005585 /* Start processes */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005586 status = MPEGTSStart(state);
5587 if (status < 0)
5588 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005589 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005590 if (status < 0)
5591 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005592 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005593 if (status < 0)
5594 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005595 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005596 if (status < 0)
5597 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005598
Oliver Endrissebc7de22011-07-03 13:49:44 -03005599 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005600 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5601 if (status < 0)
5602 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005603
Oliver Endrissebc7de22011-07-03 13:49:44 -03005604 /* update global DRXK data container */
5605 /*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005606
Oliver Endrissebc7de22011-07-03 13:49:44 -03005607 /* All done, all OK */
5608 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005609
Oliver Endrissebc7de22011-07-03 13:49:44 -03005610 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005611 printk(KERN_ERR "drxk: %s %d\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005612
5613 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005614}
5615
Oliver Endrissebc7de22011-07-03 13:49:44 -03005616static int SetQAMStandard(struct drxk_state *state,
5617 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005618{
5619#ifdef DRXK_QAM_TAPS
5620#define DRXK_QAMA_TAPS_SELECT
5621#include "drxk_filters.h"
5622#undef DRXK_QAMA_TAPS_SELECT
5623#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03005624 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005625#endif
5626
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005627 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005628 do {
5629 /* added antenna switch */
5630 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005631
Oliver Endrissebc7de22011-07-03 13:49:44 -03005632 /* Ensure correct power-up mode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005633 status = PowerUpQAM(state);
5634 if (status < 0)
5635 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005636 /* Reset QAM block */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005637 status = QAMResetQAM(state);
5638 if (status < 0)
5639 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005640
Oliver Endrissebc7de22011-07-03 13:49:44 -03005641 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005642
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005643 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005644 if (status < 0)
5645 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005646 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005647 if (status < 0)
5648 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005649
Oliver Endrissebc7de22011-07-03 13:49:44 -03005650 /* Upload IQM Channel Filter settings by
5651 boot loader from ROM table */
5652 switch (oMode) {
5653 case OM_QAM_ITU_A:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005654 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5655 if (status < 0)
5656 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005657 break;
5658 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005659 status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5660 if (status < 0)
5661 break;
5662 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5663 if (status < 0)
5664 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005665 break;
5666 default:
5667 status = -EINVAL;
5668 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005669 status = status;
5670 if (status < 0)
5671 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005672
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005673 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005674 if (status < 0)
5675 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005676 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005677 if (status < 0)
5678 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005679 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 -03005680 if (status < 0)
5681 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005682
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005683 status = write16(state, IQM_RC_STRETCH__A, 21);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005684 if (status < 0)
5685 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005686 status = write16(state, IQM_AF_CLP_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005687 if (status < 0)
5688 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005689 status = write16(state, IQM_AF_CLP_TH__A, 448);
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_SNS_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_CF_POW_MEAS_LEN__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005696 if (status < 0)
5697 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005698
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005699 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005700 if (status < 0)
5701 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005702 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005703 if (status < 0)
5704 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005705 status = write16(state, IQM_CF_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_AF_UPD_SEL__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005709 if (status < 0)
5710 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005711
Oliver Endrissebc7de22011-07-03 13:49:44 -03005712 /* IQM Impulse Noise Processing Unit */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005713 status = write16(state, IQM_CF_CLP_VAL__A, 500);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005714 if (status < 0)
5715 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005716 status = write16(state, IQM_CF_DATATH__A, 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005717 if (status < 0)
5718 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005719 status = write16(state, IQM_CF_BYPASSDET__A, 1);
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_DET_LCT__A, 0);
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_WND_LEN__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_PKDTH__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005729 if (status < 0)
5730 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005731 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005732 if (status < 0)
5733 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005734
Oliver Endrissebc7de22011-07-03 13:49:44 -03005735 /* turn on IQMAF. Must be done before setAgc**() */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005736 status = SetIqmAf(state, true);
5737 if (status < 0)
5738 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005739 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005740 if (status < 0)
5741 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005742
Oliver Endrissebc7de22011-07-03 13:49:44 -03005743 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005744 status = ADCSynchronization(state);
5745 if (status < 0)
5746 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005747
Oliver Endrissebc7de22011-07-03 13:49:44 -03005748 /* Set the FSM step period */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005749 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005750 if (status < 0)
5751 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005752
Oliver Endrissebc7de22011-07-03 13:49:44 -03005753 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005754 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005755 if (status < 0)
5756 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005757
Oliver Endrissebc7de22011-07-03 13:49:44 -03005758 /* No more resets of the IQM, current standard correctly set =>
5759 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005760
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005761 status = InitAGC(state, true);
5762 if (status < 0)
5763 break;
5764 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5765 if (status < 0)
5766 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005767
Oliver Endrissebc7de22011-07-03 13:49:44 -03005768 /* Configure AGC's */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005769 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5770 if (status < 0)
5771 break;
5772 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5773 if (status < 0)
5774 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005775
Oliver Endrissebc7de22011-07-03 13:49:44 -03005776 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005777 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005778 if (status < 0)
5779 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005780 } while (0);
5781 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005782}
5783
5784static int WriteGPIO(struct drxk_state *state)
5785{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005786 int status;
5787 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005788
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005789 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005790 do {
5791 /* stop lock indicator process */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005792 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005793 if (status < 0)
5794 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005795
Oliver Endrissebc7de22011-07-03 13:49:44 -03005796 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005797 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005798 if (status < 0)
5799 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005800
Oliver Endrissebc7de22011-07-03 13:49:44 -03005801 if (state->m_hasSAWSW) {
5802 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005803 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
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 /* use corresponding bit in io data output registar */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005808 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005809 if (status < 0)
5810 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005811 if (state->m_GPIO == 0)
5812 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5813 else
5814 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5815 /* write back to io data output register */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005816 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005817 if (status < 0)
5818 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005819
Oliver Endrissebc7de22011-07-03 13:49:44 -03005820 }
5821 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005822 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005823 if (status < 0)
5824 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005825 } while (0);
5826 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005827}
5828
5829static int SwitchAntennaToQAM(struct drxk_state *state)
5830{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005831 int status = -1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005832
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005833 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005834 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5835 if (state->m_GPIO != state->m_AntennaDVBC) {
5836 state->m_GPIO = state->m_AntennaDVBC;
5837 status = WriteGPIO(state);
5838 }
5839 }
5840 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005841}
5842
5843static int SwitchAntennaToDVBT(struct drxk_state *state)
5844{
5845 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005846
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005847 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005848 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5849 if (state->m_GPIO != state->m_AntennaDVBT) {
5850 state->m_GPIO = state->m_AntennaDVBT;
5851 status = WriteGPIO(state);
5852 }
5853 }
5854 return status;
5855}
5856
5857
5858static int PowerDownDevice(struct drxk_state *state)
5859{
5860 /* Power down to requested mode */
5861 /* Backup some register settings */
5862 /* Set pins with possible pull-ups connected to them in input mode */
5863 /* Analog power down */
5864 /* ADC power down */
5865 /* Power down device */
5866 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005867
5868 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005869 do {
5870 if (state->m_bPDownOpenBridge) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03005871 /* Open I2C bridge before power down of DRXK */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005872 status = ConfigureI2CBridge(state, true);
5873 if (status < 0)
5874 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005875 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005876 /* driver 0.9.0 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005877 status = DVBTEnableOFDMTokenRing(state, false);
5878 if (status < 0)
5879 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005880
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005881 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005882 if (status < 0)
5883 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005884 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005885 if (status < 0)
5886 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005887 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005888 status = HI_CfgCommand(state);
5889 if (status < 0)
5890 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005891 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005892
Oliver Endrissebc7de22011-07-03 13:49:44 -03005893 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005894 return -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005895
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005896 return 0;
5897}
5898
5899static int load_microcode(struct drxk_state *state, char *mc_name)
5900{
5901 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005902 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005903
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005904 dprintk(1, "\n");
5905
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005906 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5907 if (err < 0) {
5908 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005909 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005910 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005911 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005912 return err;
5913 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005914 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005915 release_firmware(fw);
5916 return err;
5917}
5918
5919static int init_drxk(struct drxk_state *state)
5920{
5921 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005922 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005923 u16 driverVersion;
5924
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005925 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005926 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
5927 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005928 status = PowerUpDevice(state);
5929 if (status < 0)
5930 break;
5931 status = DRXX_Open(state);
5932 if (status < 0)
5933 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005934 /* Soft reset of OFDM-, sys- and osc-clockdomain */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005935 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 -03005936 if (status < 0)
5937 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005938 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005939 if (status < 0)
5940 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005941 /* TODO is this needed, if yes how much delay in worst case scenario */
5942 msleep(1);
5943 state->m_DRXK_A3_PATCH_CODE = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005944 status = GetDeviceCapabilities(state);
5945 if (status < 0)
5946 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005947
5948 /* Bridge delay, uses oscilator clock */
5949 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5950 /* SDA brdige delay */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005951 state->m_HICfgBridgeDelay =
5952 (u16) ((state->m_oscClockFreq / 1000) *
5953 HI_I2C_BRIDGE_DELAY) / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005954 /* Clipping */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005955 if (state->m_HICfgBridgeDelay >
5956 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
5957 state->m_HICfgBridgeDelay =
5958 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005959 }
5960 /* SCL bridge delay, same as SDA for now */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005961 state->m_HICfgBridgeDelay +=
5962 state->m_HICfgBridgeDelay <<
5963 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005964
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005965 status = InitHI(state);
5966 if (status < 0)
5967 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005968 /* disable various processes */
5969#if NOA1ROM
Oliver Endrissebc7de22011-07-03 13:49:44 -03005970 if (!(state->m_DRXK_A1_ROM_CODE)
5971 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005972#endif
5973 {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005974 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005975 if (status < 0)
5976 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005977 }
5978
5979 /* disable MPEG port */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005980 status = MPEGTSDisable(state);
5981 if (status < 0)
5982 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005983
5984 /* Stop AUD and SCU */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005985 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005986 if (status < 0)
5987 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005988 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005989 if (status < 0)
5990 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005991
5992 /* enable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005993 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 -03005994 if (status < 0)
5995 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005996
5997 /* include boot loader section */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03005998 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005999 if (status < 0)
6000 break;
6001 status = BLChainCmd(state, 0, 6, 100);
6002 if (status < 0)
6003 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006004
6005#if 0
6006 if (state->m_DRXK_A3_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006007 status = DownloadMicrocode(state, DRXK_A3_microcode, DRXK_A3_microcode_length);
6008 if (status < 0)
6009 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006010#else
6011 load_microcode(state, "drxk_a3.mc");
6012#endif
6013#if NOA1ROM
6014 if (state->m_DRXK_A2_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006015 status = DownloadMicrocode(state, DRXK_A2_microcode, DRXK_A2_microcode_length);
6016 if (status < 0)
6017 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006018#endif
6019 /* disable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006020 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006021 if (status < 0)
6022 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006023
6024 /* Run SCU for a little while to initialize microcode version numbers */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006025 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006026 if (status < 0)
6027 break;
6028 status = DRXX_Open(state);
6029 if (status < 0)
6030 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006031 /* added for test */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006032 msleep(30);
6033
6034 powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006035 status = CtrlPowerMode(state, &powerMode);
6036 if (status < 0)
6037 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006038
6039 /* Stamp driver version number in SCU data RAM in BCD code
6040 Done to enable field application engineers to retreive drxdriver version
6041 via I2C from SCU RAM.
6042 Not using SCU command interface for SCU register access since no
6043 microcode may be present.
Oliver Endrissebc7de22011-07-03 13:49:44 -03006044 */
6045 driverVersion =
6046 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6047 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6048 ((DRXK_VERSION_MAJOR % 10) << 4) +
6049 (DRXK_VERSION_MINOR % 10);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006050 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006051 if (status < 0)
6052 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006053 driverVersion =
6054 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6055 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6056 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6057 (DRXK_VERSION_PATCH % 10);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006058 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006059 if (status < 0)
6060 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006061
Oliver Endrissebc7de22011-07-03 13:49:44 -03006062 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6063 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6064 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006065
6066 /* Dirty fix of default values for ROM/PATCH microcode
6067 Dirty because this fix makes it impossible to setup suitable values
6068 before calling DRX_Open. This solution requires changes to RF AGC speed
6069 to be done via the CTRL function after calling DRX_Open */
6070
Oliver Endrissebc7de22011-07-03 13:49:44 -03006071 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006072
6073 /* Reset driver debug flags to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006074 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006075 if (status < 0)
6076 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006077 /* driver 0.9.0 */
6078 /* Setup FEC OC:
6079 NOTE: No more full FEC resets allowed afterwards!! */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03006080 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006081 if (status < 0)
6082 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006083 /* MPEGTS functions are still the same */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006084 status = MPEGTSDtoInit(state);
6085 if (status < 0)
6086 break;
6087 status = MPEGTSStop(state);
6088 if (status < 0)
6089 break;
6090 status = MPEGTSConfigurePolarity(state);
6091 if (status < 0)
6092 break;
6093 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6094 if (status < 0)
6095 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006096 /* added: configure GPIO */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006097 status = WriteGPIO(state);
6098 if (status < 0)
6099 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006100
Oliver Endrissebc7de22011-07-03 13:49:44 -03006101 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006102
6103 if (state->m_bPowerDown) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006104 status = PowerDownDevice(state);
6105 if (status < 0)
6106 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006107 state->m_DrxkState = DRXK_POWERED_DOWN;
6108 } else
6109 state->m_DrxkState = DRXK_STOPPED;
6110 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006111 }
6112
6113 return 0;
6114}
6115
Oliver Endrissebc7de22011-07-03 13:49:44 -03006116static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006117{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006118 struct drxk_state *state = fe->demodulator_priv;
6119
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006120 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006121 kfree(state);
6122}
6123
Oliver Endrissebc7de22011-07-03 13:49:44 -03006124static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006125{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006126 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006127
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006128 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006129 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006130 return -EBUSY;
6131 SetOperationMode(state, OM_QAM_ITU_A);
6132 return 0;
6133}
6134
Oliver Endrissebc7de22011-07-03 13:49:44 -03006135static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006136{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006137 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006138
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006139 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006140 ShutDown(state);
6141 mutex_unlock(&state->ctlock);
6142 return 0;
6143}
6144
Oliver Endrissebc7de22011-07-03 13:49:44 -03006145static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006146{
6147 struct drxk_state *state = fe->demodulator_priv;
6148
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006149 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006150 return ConfigureI2CBridge(state, enable ? true : false);
6151}
6152
Oliver Endrissebc7de22011-07-03 13:49:44 -03006153static int drxk_set_parameters(struct dvb_frontend *fe,
6154 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006155{
6156 struct drxk_state *state = fe->demodulator_priv;
6157 u32 IF;
6158
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006159 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006160 if (fe->ops.i2c_gate_ctrl)
6161 fe->ops.i2c_gate_ctrl(fe, 1);
6162 if (fe->ops.tuner_ops.set_params)
6163 fe->ops.tuner_ops.set_params(fe, p);
6164 if (fe->ops.i2c_gate_ctrl)
6165 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006166 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006167 fe->ops.tuner_ops.get_frequency(fe, &IF);
6168 Start(state, 0, IF);
6169
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006170 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006171
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006172 return 0;
6173}
6174
Oliver Endrissebc7de22011-07-03 13:49:44 -03006175static int drxk_c_get_frontend(struct dvb_frontend *fe,
6176 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006177{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006178 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006179 return 0;
6180}
6181
6182static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6183{
6184 struct drxk_state *state = fe->demodulator_priv;
6185 u32 stat;
6186
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006187 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006188 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006189 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006190 if (stat == MPEG_LOCK)
6191 *status |= 0x1f;
6192 if (stat == FEC_LOCK)
6193 *status |= 0x0f;
6194 if (stat == DEMOD_LOCK)
6195 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006196 return 0;
6197}
6198
6199static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6200{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006201 dprintk(1, "\n");
6202
Oliver Endrissebc7de22011-07-03 13:49:44 -03006203 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006204 return 0;
6205}
6206
Oliver Endrissebc7de22011-07-03 13:49:44 -03006207static int drxk_read_signal_strength(struct dvb_frontend *fe,
6208 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006209{
6210 struct drxk_state *state = fe->demodulator_priv;
6211 u32 val;
6212
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006213 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006214 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006215 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006216 return 0;
6217}
6218
6219static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6220{
6221 struct drxk_state *state = fe->demodulator_priv;
6222 s32 snr2;
6223
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006224 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006225 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006226 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006227 return 0;
6228}
6229
6230static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6231{
6232 struct drxk_state *state = fe->demodulator_priv;
6233 u16 err;
6234
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006235 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006236 DVBTQAMGetAccPktErr(state, &err);
6237 *ucblocks = (u32) err;
6238 return 0;
6239}
6240
Oliver Endrissebc7de22011-07-03 13:49:44 -03006241static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6242 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006243{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006244 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006245 sets->min_delay_ms = 3000;
6246 sets->max_drift = 0;
6247 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006248 return 0;
6249}
6250
Oliver Endrissebc7de22011-07-03 13:49:44 -03006251static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006252{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006253#if 0
6254 struct drxk_state *state = fe->demodulator_priv;
6255
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006256 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006257 kfree(state);
6258#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006259}
6260
Oliver Endrissebc7de22011-07-03 13:49:44 -03006261static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006262{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006263 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006264
6265 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006266 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006267 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006268 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006269 return 0;
6270}
6271
Oliver Endrissebc7de22011-07-03 13:49:44 -03006272static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006273{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006274 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006275
6276 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006277 mutex_unlock(&state->ctlock);
6278 return 0;
6279}
6280
Oliver Endrissebc7de22011-07-03 13:49:44 -03006281static int drxk_t_get_frontend(struct dvb_frontend *fe,
6282 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006283{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006284 dprintk(1, "\n");
6285
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006286 return 0;
6287}
6288
6289static struct dvb_frontend_ops drxk_c_ops = {
6290 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006291 .name = "DRXK DVB-C",
6292 .type = FE_QAM,
6293 .frequency_stepsize = 62500,
6294 .frequency_min = 47000000,
6295 .frequency_max = 862000000,
6296 .symbol_rate_min = 870000,
6297 .symbol_rate_max = 11700000,
6298 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6299 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006300 .release = drxk_c_release,
6301 .init = drxk_c_init,
6302 .sleep = drxk_c_sleep,
6303 .i2c_gate_ctrl = drxk_gate_ctrl,
6304
6305 .set_frontend = drxk_set_parameters,
6306 .get_frontend = drxk_c_get_frontend,
6307 .get_tune_settings = drxk_c_get_tune_settings,
6308
6309 .read_status = drxk_read_status,
6310 .read_ber = drxk_read_ber,
6311 .read_signal_strength = drxk_read_signal_strength,
6312 .read_snr = drxk_read_snr,
6313 .read_ucblocks = drxk_read_ucblocks,
6314};
6315
6316static struct dvb_frontend_ops drxk_t_ops = {
6317 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006318 .name = "DRXK DVB-T",
6319 .type = FE_OFDM,
6320 .frequency_min = 47125000,
6321 .frequency_max = 865000000,
6322 .frequency_stepsize = 166667,
6323 .frequency_tolerance = 0,
6324 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6325 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6326 FE_CAN_FEC_AUTO |
6327 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6328 FE_CAN_QAM_AUTO |
6329 FE_CAN_TRANSMISSION_MODE_AUTO |
6330 FE_CAN_GUARD_INTERVAL_AUTO |
6331 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006332 .release = drxk_t_release,
6333 .init = drxk_t_init,
6334 .sleep = drxk_t_sleep,
6335 .i2c_gate_ctrl = drxk_gate_ctrl,
6336
6337 .set_frontend = drxk_set_parameters,
6338 .get_frontend = drxk_t_get_frontend,
6339
6340 .read_status = drxk_read_status,
6341 .read_ber = drxk_read_ber,
6342 .read_signal_strength = drxk_read_signal_strength,
6343 .read_snr = drxk_read_snr,
6344 .read_ucblocks = drxk_read_ucblocks,
6345};
6346
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006347struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6348 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006349 struct dvb_frontend **fe_t)
6350{
6351 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006352 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006353
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006354 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006355 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006356 if (!state)
6357 return NULL;
6358
Oliver Endrissebc7de22011-07-03 13:49:44 -03006359 state->i2c = i2c;
6360 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006361 state->single_master = config->single_master;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006362
6363 mutex_init(&state->mutex);
6364 mutex_init(&state->ctlock);
6365
Oliver Endrissebc7de22011-07-03 13:49:44 -03006366 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6367 sizeof(struct dvb_frontend_ops));
6368 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6369 sizeof(struct dvb_frontend_ops));
6370 state->c_frontend.demodulator_priv = state;
6371 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006372
6373 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006374 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006375 goto error;
6376 *fe_t = &state->t_frontend;
6377 return &state->c_frontend;
6378
6379error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006380 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006381 kfree(state);
6382 return NULL;
6383}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006384EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006385
6386MODULE_DESCRIPTION("DRX-K driver");
6387MODULE_AUTHOR("Ralph Metzler");
6388MODULE_LICENSE("GPL");