blob: fe944592294236e787beef3ddc7788e0e1954b1a [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
375static int Read16(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
376{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300377 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300378#ifdef I2C_LONG_ADR
379 flags |= 0xC0;
380#endif
381 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
382 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
383 mm1[1] = ((reg >> 16) & 0xFF);
384 mm1[2] = ((reg >> 24) & 0xFF) | flags;
385 mm1[3] = ((reg >> 7) & 0xFF);
386 len = 4;
387 } else {
388 mm1[0] = ((reg << 1) & 0xFF);
389 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
390 len = 2;
391 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300392 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300393 if (i2c_read(state->i2c, adr, mm1, len, mm2, 2) < 0)
394 return -1;
395 if (data)
396 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300397
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300398 return 0;
399}
400
401static int Read16_0(struct drxk_state *state, u32 reg, u16 *data)
402{
403 return Read16(state, reg, data, 0);
404}
405
406static int Read32(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
407{
408 u8 adr = state->demod_address, mm1[4], mm2[4], len;
409#ifdef I2C_LONG_ADR
410 flags |= 0xC0;
411#endif
412 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
413 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
414 mm1[1] = ((reg >> 16) & 0xFF);
415 mm1[2] = ((reg >> 24) & 0xFF) | flags;
416 mm1[3] = ((reg >> 7) & 0xFF);
417 len = 4;
418 } else {
419 mm1[0] = ((reg << 1) & 0xFF);
420 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
421 len = 2;
422 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300423 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300424 if (i2c_read(state->i2c, adr, mm1, len, mm2, 4) < 0)
425 return -1;
426 if (data)
427 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300428 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300429
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300430 return 0;
431}
432
433static int Write16(struct drxk_state *state, u32 reg, u16 data, u8 flags)
434{
435 u8 adr = state->demod_address, mm[6], len;
436#ifdef I2C_LONG_ADR
437 flags |= 0xC0;
438#endif
439 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
440 mm[0] = (((reg << 1) & 0xFF) | 0x01);
441 mm[1] = ((reg >> 16) & 0xFF);
442 mm[2] = ((reg >> 24) & 0xFF) | flags;
443 mm[3] = ((reg >> 7) & 0xFF);
444 len = 4;
445 } else {
446 mm[0] = ((reg << 1) & 0xFF);
447 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
448 len = 2;
449 }
450 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300451 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300452
453 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300454 if (i2c_write(state->i2c, adr, mm, len + 2) < 0)
455 return -1;
456 return 0;
457}
458
459static int Write16_0(struct drxk_state *state, u32 reg, u16 data)
460{
461 return Write16(state, reg, data, 0);
462}
463
464static int Write32(struct drxk_state *state, u32 reg, u32 data, u8 flags)
465{
466 u8 adr = state->demod_address, mm[8], len;
467#ifdef I2C_LONG_ADR
468 flags |= 0xC0;
469#endif
470 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
471 mm[0] = (((reg << 1) & 0xFF) | 0x01);
472 mm[1] = ((reg >> 16) & 0xFF);
473 mm[2] = ((reg >> 24) & 0xFF) | flags;
474 mm[3] = ((reg >> 7) & 0xFF);
475 len = 4;
476 } else {
477 mm[0] = ((reg << 1) & 0xFF);
478 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
479 len = 2;
480 }
481 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300482 mm[len + 1] = (data >> 8) & 0xff;
483 mm[len + 2] = (data >> 16) & 0xff;
484 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300485 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300486 if (i2c_write(state->i2c, adr, mm, len + 4) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300487 return -1;
488 return 0;
489}
490
491static int WriteBlock(struct drxk_state *state, u32 Address,
492 const int BlockSize, const u8 pBlock[], u8 Flags)
493{
494 int status = 0, BlkSize = BlockSize;
495#ifdef I2C_LONG_ADR
496 Flags |= 0xC0;
497#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -0300498 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300499 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300500 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300501 u8 *AdrBuf = &state->Chunk[0];
502 u32 AdrLength = 0;
503
Oliver Endrissebc7de22011-07-03 13:49:44 -0300504 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
505 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
506 AdrBuf[1] = ((Address >> 16) & 0xFF);
507 AdrBuf[2] = ((Address >> 24) & 0xFF);
508 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300509 AdrBuf[2] |= Flags;
510 AdrLength = 4;
511 if (Chunk == state->m_ChunkSize)
512 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300513 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300514 AdrBuf[0] = ((Address << 1) & 0xFF);
515 AdrBuf[1] = (((Address >> 16) & 0x0F) |
516 ((Address >> 18) & 0xF0));
517 AdrLength = 2;
518 }
519 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300520 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
521 if (debug > 1) {
522 int i;
523 if (pBlock)
524 for (i = 0; i < Chunk; i++)
525 printk(KERN_CONT " %02x", pBlock[i]);
526 printk(KERN_CONT "\n");
527 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300528 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300529 &state->Chunk[0], Chunk + AdrLength);
530 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300531 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
532 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300533 break;
534 }
535 pBlock += Chunk;
536 Address += (Chunk >> 1);
537 BlkSize -= Chunk;
538 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300539 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300540}
541
542#ifndef DRXK_MAX_RETRIES_POWERUP
543#define DRXK_MAX_RETRIES_POWERUP 20
544#endif
545
546int PowerUpDevice(struct drxk_state *state)
547{
548 int status;
549 u8 data = 0;
550 u16 retryCount = 0;
551
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300552 dprintk(1, "\n");
553
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300554 status = i2c_read1(state->i2c, state->demod_address, &data);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300555 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300556 do {
557 data = 0;
558 if (i2c_write(state->i2c,
559 state->demod_address, &data, 1) < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300560 printk(KERN_ERR "drxk: powerup failed\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300561 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300562 retryCount++;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300563 } while (i2c_read1(state->i2c,
564 state->demod_address, &data) < 0 &&
565 (retryCount < DRXK_MAX_RETRIES_POWERUP));
566 if (retryCount >= DRXK_MAX_RETRIES_POWERUP)
567 return -1;
568 do {
569 /* Make sure all clk domains are active */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300570 status = Write16_0(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
571 if (status < 0)
572 break;
573 status = Write16_0(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
574 if (status < 0)
575 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300576 /* Enable pll lock tests */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300577 status = Write16_0(state, SIO_CC_PLL_LOCK__A, 1);
578 if (status < 0)
579 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300580 state->m_currentPowerMode = DRX_POWER_UP;
581 } while (0);
582 return status;
583}
584
585
586static int init_state(struct drxk_state *state)
587{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300588 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
589 u32 ulVSBIfAgcOutputLevel = 0;
590 u32 ulVSBIfAgcMinLevel = 0;
591 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
592 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300593
Oliver Endrissebc7de22011-07-03 13:49:44 -0300594 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
595 u32 ulVSBRfAgcOutputLevel = 0;
596 u32 ulVSBRfAgcMinLevel = 0;
597 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
598 u32 ulVSBRfAgcSpeed = 3;
599 u32 ulVSBRfAgcTop = 9500;
600 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300601
Oliver Endrissebc7de22011-07-03 13:49:44 -0300602 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
603 u32 ulATVIfAgcOutputLevel = 0;
604 u32 ulATVIfAgcMinLevel = 0;
605 u32 ulATVIfAgcMaxLevel = 0;
606 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300607
Oliver Endrissebc7de22011-07-03 13:49:44 -0300608 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
609 u32 ulATVRfAgcOutputLevel = 0;
610 u32 ulATVRfAgcMinLevel = 0;
611 u32 ulATVRfAgcMaxLevel = 0;
612 u32 ulATVRfAgcTop = 9500;
613 u32 ulATVRfAgcCutOffCurrent = 4000;
614 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300615
616 u32 ulQual83 = DEFAULT_MER_83;
617 u32 ulQual93 = DEFAULT_MER_93;
618
619 u32 ulDVBTStaticTSClock = 1;
620 u32 ulDVBCStaticTSClock = 1;
621
622 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
623 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
624
625 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
626 /* io_pad_cfg_mode output mode is drive always */
627 /* io_pad_cfg_drive is set to power 2 (23 mA) */
628 u32 ulGPIOCfg = 0x0113;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300629 u32 ulGPIO = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300630 u32 ulSerialMode = 1;
631 u32 ulInvertTSClock = 0;
632 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
633 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
634 u32 ulDVBTBitrate = 50000000;
635 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
636
637 u32 ulInsertRSByte = 0;
638
639 u32 ulRfMirror = 1;
640 u32 ulPowerDown = 0;
641
642 u32 ulAntennaDVBT = 1;
643 u32 ulAntennaDVBC = 0;
644 u32 ulAntennaSwitchDVBTDVBC = 0;
645
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300646 dprintk(1, "\n");
647
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300648 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300649 state->m_hasDVBT = false;
650 state->m_hasDVBC = false;
651 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300652 state->m_hasOOB = false;
653 state->m_hasAudio = false;
654
655 state->m_ChunkSize = 124;
656
657 state->m_oscClockFreq = 0;
658 state->m_smartAntInverted = false;
659 state->m_bPDownOpenBridge = false;
660
661 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300662 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300663 /* Timing div, 250ns/Psys */
664 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
665 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
666 HI_I2C_DELAY) / 1000;
667 /* Clipping */
668 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
669 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
670 state->m_HICfgWakeUpKey = (state->demod_address << 1);
671 /* port/bridge/power down ctrl */
672 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
673
674 state->m_bPowerDown = (ulPowerDown != 0);
675
676 state->m_DRXK_A1_PATCH_CODE = false;
677 state->m_DRXK_A1_ROM_CODE = false;
678 state->m_DRXK_A2_ROM_CODE = false;
679 state->m_DRXK_A3_ROM_CODE = false;
680 state->m_DRXK_A2_PATCH_CODE = false;
681 state->m_DRXK_A3_PATCH_CODE = false;
682
683 /* Init AGC and PGA parameters */
684 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300685 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
686 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
687 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
688 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
689 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300690 state->m_vsbPgaCfg = 140;
691
692 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300693 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
694 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
695 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
696 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
697 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
698 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
699 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
700 state->m_vsbPreSawCfg.reference = 0x07;
701 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300702
703 state->m_Quality83percent = DEFAULT_MER_83;
704 state->m_Quality93percent = DEFAULT_MER_93;
705 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
706 state->m_Quality83percent = ulQual83;
707 state->m_Quality93percent = ulQual93;
708 }
709
710 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300711 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
712 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
713 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
714 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
715 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300716
717 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300718 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
719 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
720 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
721 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
722 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
723 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
724 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
725 state->m_atvPreSawCfg.reference = 0x04;
726 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300727
728
729 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300730 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
731 state->m_dvbtRfAgcCfg.outputLevel = 0;
732 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
733 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
734 state->m_dvbtRfAgcCfg.top = 0x2100;
735 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
736 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300737
738
739 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300740 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
741 state->m_dvbtIfAgcCfg.outputLevel = 0;
742 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
743 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
744 state->m_dvbtIfAgcCfg.top = 13424;
745 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
746 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300747 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300748 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
749 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300750
Oliver Endrissebc7de22011-07-03 13:49:44 -0300751 state->m_dvbtPreSawCfg.reference = 4;
752 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300753
754 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300755 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
756 state->m_qamRfAgcCfg.outputLevel = 0;
757 state->m_qamRfAgcCfg.minOutputLevel = 6023;
758 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
759 state->m_qamRfAgcCfg.top = 0x2380;
760 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
761 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300762
763 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300764 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
765 state->m_qamIfAgcCfg.outputLevel = 0;
766 state->m_qamIfAgcCfg.minOutputLevel = 0;
767 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
768 state->m_qamIfAgcCfg.top = 0x0511;
769 state->m_qamIfAgcCfg.cutOffCurrent = 0;
770 state->m_qamIfAgcCfg.speed = 3;
771 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300772 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
773
Oliver Endrissebc7de22011-07-03 13:49:44 -0300774 state->m_qamPgaCfg = 140;
775 state->m_qamPreSawCfg.reference = 4;
776 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300777
778 state->m_OperationMode = OM_NONE;
779 state->m_DrxkState = DRXK_UNINITIALIZED;
780
781 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300782 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
783 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
784 state->m_enableParallel = true; /* If TRUE;
785 parallel out otherwise serial */
786 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
787 state->m_invertERR = false; /* If TRUE; invert ERR signal */
788 state->m_invertSTR = false; /* If TRUE; invert STR signals */
789 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
790 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300791 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300792 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300793 /* If TRUE; static MPEG clockrate will be used;
794 otherwise clockrate will adapt to the bitrate of the TS */
795
796 state->m_DVBTBitrate = ulDVBTBitrate;
797 state->m_DVBCBitrate = ulDVBCBitrate;
798
799 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
800 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
801
802 /* Maximum bitrate in b/s in case static clockrate is selected */
803 state->m_mpegTsStaticBitrate = 19392658;
804 state->m_disableTEIhandling = false;
805
806 if (ulInsertRSByte)
807 state->m_insertRSByte = true;
808
809 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
810 if (ulMpegLockTimeOut < 10000)
811 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
812 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
813 if (ulDemodLockTimeOut < 10000)
814 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
815
Oliver Endrissebc7de22011-07-03 13:49:44 -0300816 /* QAM defaults */
817 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300818 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300819 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
820 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300821
822 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
823 state->m_agcFastClipCtrlDelay = 0;
824
825 state->m_GPIOCfg = (ulGPIOCfg);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300826 state->m_GPIO = (ulGPIO == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300827
828 state->m_AntennaDVBT = (ulAntennaDVBT == 0 ? 0 : 1);
829 state->m_AntennaDVBC = (ulAntennaDVBC == 0 ? 0 : 1);
830 state->m_AntennaSwitchDVBTDVBC =
Oliver Endrissebc7de22011-07-03 13:49:44 -0300831 (ulAntennaSwitchDVBTDVBC == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300832
833 state->m_bPowerDown = false;
834 state->m_currentPowerMode = DRX_POWER_DOWN;
835
836 state->m_enableParallel = (ulSerialMode == 0);
837
838 state->m_rfmirror = (ulRfMirror == 0);
839 state->m_IfAgcPol = false;
840 return 0;
841}
842
843static int DRXX_Open(struct drxk_state *state)
844{
845 int status = 0;
846 u32 jtag = 0;
847 u16 bid = 0;
848 u16 key = 0;
849
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300850 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300851 do {
852 /* stop lock indicator process */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300853 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
854 if (status < 0)
855 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300856 /* Check device id */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300857 status = Read16(state, SIO_TOP_COMM_KEY__A, &key, 0);
858 if (status < 0)
859 break;
860 status = Write16_0(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
861 if (status < 0)
862 break;
863 status = Read32(state, SIO_TOP_JTAGID_LO__A, &jtag, 0);
864 if (status < 0)
865 break;
866 status = Read16(state, SIO_PDR_UIO_IN_HI__A, &bid, 0);
867 if (status < 0)
868 break;
869 status = Write16_0(state, SIO_TOP_COMM_KEY__A, key);
870 if (status < 0)
871 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300872 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300873 return status;
874}
875
876static int GetDeviceCapabilities(struct drxk_state *state)
877{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300878 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300879 u32 sioTopJtagidLo = 0;
880 int status;
881
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300882 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300883 do {
884 /* driver 0.9.0 */
885 /* stop lock indicator process */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300886 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
887 if (status < 0)
888 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300889
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300890 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0xFABA);
891 if (status < 0)
892 break;
893 status = Read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg, 0);
894 if (status < 0)
895 break;
896 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0x0000);
897 if (status < 0)
898 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300899
900 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
901 case 0:
902 /* ignore (bypass ?) */
903 break;
904 case 1:
905 /* 27 MHz */
906 state->m_oscClockFreq = 27000;
907 break;
908 case 2:
909 /* 20.25 MHz */
910 state->m_oscClockFreq = 20250;
911 break;
912 case 3:
913 /* 4 MHz */
914 state->m_oscClockFreq = 20250;
915 break;
916 default:
917 return -1;
918 }
919 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300920 Determine device capabilities
921 Based on pinning v14
922 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300923 status = Read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo, 0);
924 if (status < 0)
925 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300926 /* driver 0.9.0 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300927 switch ((sioTopJtagidLo >> 29) & 0xF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300928 case 0:
929 state->m_deviceSpin = DRXK_SPIN_A1;
930 break;
931 case 2:
932 state->m_deviceSpin = DRXK_SPIN_A2;
933 break;
934 case 3:
935 state->m_deviceSpin = DRXK_SPIN_A3;
936 break;
937 default:
938 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
939 status = -1;
940 break;
941 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300942 switch ((sioTopJtagidLo >> 12) & 0xFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300943 case 0x13:
944 /* typeId = DRX3913K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300945 state->m_hasLNA = false;
946 state->m_hasOOB = false;
947 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300948 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300949 state->m_hasDVBT = true;
950 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300951 state->m_hasSAWSW = true;
952 state->m_hasGPIO2 = false;
953 state->m_hasGPIO1 = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300954 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300955 break;
956 case 0x15:
957 /* typeId = DRX3915K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300958 state->m_hasLNA = false;
959 state->m_hasOOB = false;
960 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300961 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300962 state->m_hasDVBT = true;
963 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300964 state->m_hasSAWSW = true;
965 state->m_hasGPIO2 = true;
966 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300967 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300968 break;
969 case 0x16:
970 /* typeId = DRX3916K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300971 state->m_hasLNA = false;
972 state->m_hasOOB = false;
973 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300974 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300975 state->m_hasDVBT = true;
976 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300977 state->m_hasSAWSW = true;
978 state->m_hasGPIO2 = true;
979 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300980 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300981 break;
982 case 0x18:
983 /* typeId = DRX3918K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300984 state->m_hasLNA = false;
985 state->m_hasOOB = false;
986 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300987 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300988 state->m_hasDVBT = true;
989 state->m_hasDVBC = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300990 state->m_hasSAWSW = true;
991 state->m_hasGPIO2 = true;
992 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300993 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300994 break;
995 case 0x21:
996 /* typeId = DRX3921K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300997 state->m_hasLNA = false;
998 state->m_hasOOB = false;
999 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001000 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001001 state->m_hasDVBT = true;
1002 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001003 state->m_hasSAWSW = true;
1004 state->m_hasGPIO2 = true;
1005 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001006 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001007 break;
1008 case 0x23:
1009 /* typeId = DRX3923K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001010 state->m_hasLNA = false;
1011 state->m_hasOOB = false;
1012 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001013 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001014 state->m_hasDVBT = true;
1015 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001016 state->m_hasSAWSW = true;
1017 state->m_hasGPIO2 = true;
1018 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001019 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001020 break;
1021 case 0x25:
1022 /* typeId = DRX3925K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001023 state->m_hasLNA = false;
1024 state->m_hasOOB = false;
1025 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001026 state->m_hasAudio = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001027 state->m_hasDVBT = true;
1028 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001029 state->m_hasSAWSW = true;
1030 state->m_hasGPIO2 = true;
1031 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001032 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001033 break;
1034 case 0x26:
1035 /* typeId = DRX3926K_TYPE_ID */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001036 state->m_hasLNA = false;
1037 state->m_hasOOB = false;
1038 state->m_hasATV = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001039 state->m_hasAudio = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001040 state->m_hasDVBT = true;
1041 state->m_hasDVBC = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001042 state->m_hasSAWSW = true;
1043 state->m_hasGPIO2 = true;
1044 state->m_hasGPIO1 = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001045 state->m_hasIRQN = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001046 break;
1047 default:
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001048 printk(KERN_ERR "drxk: DeviceID not supported = %02x\n",
Oliver Endrissebc7de22011-07-03 13:49:44 -03001049 ((sioTopJtagidLo >> 12) & 0xFF));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001050 status = -1;
1051 break;
1052 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001053 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001054 return status;
1055}
1056
1057static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1058{
1059 int status;
1060 bool powerdown_cmd;
1061
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001062 dprintk(1, "\n");
1063
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001064 /* Write command */
1065 status = Write16_0(state, SIO_HI_RA_RAM_CMD__A, cmd);
1066 if (status < 0)
1067 return status;
1068 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1069 msleep(1);
1070
1071 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001072 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1073 ((state->m_HICfgCtrl) &
1074 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1075 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001076 if (powerdown_cmd == false) {
1077 /* Wait until command rdy */
1078 u32 retryCount = 0;
1079 u16 waitCmd;
1080
1081 do {
1082 msleep(1);
1083 retryCount += 1;
1084 status = Read16(state, SIO_HI_RA_RAM_CMD__A,
1085 &waitCmd, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001086 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1087 && (waitCmd != 0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001088
1089 if (status == 0)
1090 status = Read16(state, SIO_HI_RA_RAM_RES__A,
1091 pResult, 0);
1092 }
1093 return status;
1094}
1095
1096static int HI_CfgCommand(struct drxk_state *state)
1097{
1098 int status;
1099
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001100 dprintk(1, "\n");
1101
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001102 mutex_lock(&state->mutex);
1103 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001104 status = Write16_0(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1105 if (status < 0)
1106 break;
1107 status = Write16_0(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1108 if (status < 0)
1109 break;
1110 status = Write16_0(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1111 if (status < 0)
1112 break;
1113 status = Write16_0(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1114 if (status < 0)
1115 break;
1116 status = Write16_0(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1117 if (status < 0)
1118 break;
1119 status = Write16_0(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1120 if (status < 0)
1121 break;
1122 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1123 if (status < 0)
1124 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001125
1126 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001127 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001128 mutex_unlock(&state->mutex);
1129 return status;
1130}
1131
1132static int InitHI(struct drxk_state *state)
1133{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001134 dprintk(1, "\n");
1135
Oliver Endrissebc7de22011-07-03 13:49:44 -03001136 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001137 state->m_HICfgTimeout = 0x96FF;
1138 /* port/bridge/power down ctrl */
1139 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001140 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001141}
1142
1143static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1144{
1145 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001146 u16 sioPdrMclkCfg = 0;
1147 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001148
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001149 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001150 do {
1151 /* stop lock indicator process */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001152 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1153 if (status < 0)
1154 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001155
1156 /* MPEG TS pad configuration */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001157 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1158 if (status < 0)
1159 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001160
1161 if (mpegEnable == false) {
1162 /* Set MPEG TS pads to inputmode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001163 status = Write16_0(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1164 if (status < 0)
1165 break;
1166 status = Write16_0(state, SIO_PDR_MERR_CFG__A, 0x0000);
1167 if (status < 0)
1168 break;
1169 status = Write16_0(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1170 if (status < 0)
1171 break;
1172 status = Write16_0(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1173 if (status < 0)
1174 break;
1175 status = Write16_0(state, SIO_PDR_MD0_CFG__A, 0x0000);
1176 if (status < 0)
1177 break;
1178 status = Write16_0(state, SIO_PDR_MD1_CFG__A, 0x0000);
1179 if (status < 0)
1180 break;
1181 status = Write16_0(state, SIO_PDR_MD2_CFG__A, 0x0000);
1182 if (status < 0)
1183 break;
1184 status = Write16_0(state, SIO_PDR_MD3_CFG__A, 0x0000);
1185 if (status < 0)
1186 break;
1187 status = Write16_0(state, SIO_PDR_MD4_CFG__A, 0x0000);
1188 if (status < 0)
1189 break;
1190 status = Write16_0(state, SIO_PDR_MD5_CFG__A, 0x0000);
1191 if (status < 0)
1192 break;
1193 status = Write16_0(state, SIO_PDR_MD6_CFG__A, 0x0000);
1194 if (status < 0)
1195 break;
1196 status = Write16_0(state, SIO_PDR_MD7_CFG__A, 0x0000);
1197 if (status < 0)
1198 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001199 } else {
1200 /* Enable MPEG output */
1201 sioPdrMdxCfg =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001202 ((state->m_TSDataStrength <<
1203 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001204 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03001205 SIO_PDR_MCLK_CFG_DRIVE__B) |
1206 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001207
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001208 status = Write16_0(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1209 if (status < 0)
1210 break;
1211 status = Write16_0(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
1212 if (status < 0)
1213 break;
1214 status = Write16_0(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
1215 if (status < 0)
1216 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001217 if (state->m_enableParallel == true) {
1218 /* paralel -> enable MD1 to MD7 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001219 status = Write16_0(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
1220 if (status < 0)
1221 break;
1222 status = Write16_0(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
1223 if (status < 0)
1224 break;
1225 status = Write16_0(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
1226 if (status < 0)
1227 break;
1228 status = Write16_0(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
1229 if (status < 0)
1230 break;
1231 status = Write16_0(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
1232 if (status < 0)
1233 break;
1234 status = Write16_0(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1235 if (status < 0)
1236 break;
1237 status = Write16_0(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1238 if (status < 0)
1239 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001240 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001241 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1242 SIO_PDR_MD0_CFG_DRIVE__B)
1243 | 0x0003);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001244 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001245 status = Write16_0(state, SIO_PDR_MD1_CFG__A, 0x0000);
1246 if (status < 0)
1247 break;
1248 status = Write16_0(state, SIO_PDR_MD2_CFG__A, 0x0000);
1249 if (status < 0)
1250 break;
1251 status = Write16_0(state, SIO_PDR_MD3_CFG__A, 0x0000);
1252 if (status < 0)
1253 break;
1254 status = Write16_0(state, SIO_PDR_MD4_CFG__A, 0x0000);
1255 if (status < 0)
1256 break;
1257 status = Write16_0(state, SIO_PDR_MD5_CFG__A, 0x0000);
1258 if (status < 0)
1259 break;
1260 status = Write16_0(state, SIO_PDR_MD6_CFG__A, 0x0000);
1261 if (status < 0)
1262 break;
1263 status = Write16_0(state, SIO_PDR_MD7_CFG__A, 0x0000);
1264 if (status < 0)
1265 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001266 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001267 status = Write16_0(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
1268 if (status < 0)
1269 break;
1270 status = Write16_0(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
1271 if (status < 0)
1272 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001273 }
1274 /* Enable MB output over MPEG pads and ctl input */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001275 status = Write16_0(state, SIO_PDR_MON_CFG__A, 0x0000);
1276 if (status < 0)
1277 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001278 /* Write nomagic word to enable pdr reg write */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001279 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0x0000);
1280 if (status < 0)
1281 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001282 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001283 return status;
1284}
1285
1286static int MPEGTSDisable(struct drxk_state *state)
1287{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001288 dprintk(1, "\n");
1289
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001290 return MPEGTSConfigurePins(state, false);
1291}
1292
1293static int BLChainCmd(struct drxk_state *state,
1294 u16 romOffset, u16 nrOfElements, u32 timeOut)
1295{
1296 u16 blStatus = 0;
1297 int status;
1298 unsigned long end;
1299
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001300 dprintk(1, "\n");
1301
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001302 mutex_lock(&state->mutex);
1303 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001304 status = Write16_0(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1305 if (status < 0)
1306 break;
1307 status = Write16_0(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1308 if (status < 0)
1309 break;
1310 status = Write16_0(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1311 if (status < 0)
1312 break;
1313 status = Write16_0(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1314 if (status < 0)
1315 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001316 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001317
1318 do {
1319 msleep(1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001320 status = Read16(state, SIO_BL_STATUS__A, &blStatus, 0);
1321 if (status < 0)
1322 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001323 } while ((blStatus == 0x1) &&
1324 ((time_is_after_jiffies(end))));
1325 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001326 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001327 mutex_unlock(&state->mutex);
1328 return -1;
1329 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001330 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001331 mutex_unlock(&state->mutex);
1332 return status;
1333}
1334
1335
1336static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001337 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001338{
1339 const u8 *pSrc = pMCImage;
1340 u16 Flags;
1341 u16 Drain;
1342 u32 Address;
1343 u16 nBlocks;
1344 u16 BlockSize;
1345 u16 BlockCRC;
1346 u32 offset = 0;
1347 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001348 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001349
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001350 dprintk(1, "\n");
1351
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001352 /* down the drain (we don care about MAGIC_WORD) */
1353 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001354 pSrc += sizeof(u16);
1355 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001356 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001357 pSrc += sizeof(u16);
1358 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001359
1360 for (i = 0; i < nBlocks; i += 1) {
1361 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001362 (pSrc[2] << 8) | pSrc[3];
1363 pSrc += sizeof(u32);
1364 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001365
1366 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001367 pSrc += sizeof(u16);
1368 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001369
1370 Flags = (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 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001375 pSrc += sizeof(u16);
1376 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001377 status = WriteBlock(state, Address, BlockSize, pSrc, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001378 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001379 break;
1380 pSrc += BlockSize;
1381 offset += BlockSize;
1382 }
1383 return status;
1384}
1385
1386static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1387{
1388 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001389 u16 data = 0;
1390 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001391 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1392 unsigned long end;
1393
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001394 dprintk(1, "\n");
1395
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001396 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001397 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001398 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1399 }
1400
Oliver Endrissebc7de22011-07-03 13:49:44 -03001401 status = (Read16_0(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001402
1403 if (data == desiredStatus) {
1404 /* tokenring already has correct status */
1405 return status;
1406 }
1407 /* Disable/enable dvbt tokenring bridge */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001408 status =
1409 Write16_0(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001410
Oliver Endrissebc7de22011-07-03 13:49:44 -03001411 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001412 do {
1413 status = Read16_0(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1414 if (status < 0)
1415 break;
1416 } while ((data != desiredStatus) && ((time_is_after_jiffies(end))));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001417 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001418 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001419 return -1;
1420 }
1421 return status;
1422}
1423
1424static int MPEGTSStop(struct drxk_state *state)
1425{
1426 int status = 0;
1427 u16 fecOcSncMode = 0;
1428 u16 fecOcIprMode = 0;
1429
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001430 dprintk(1, "\n");
1431
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001432 do {
1433 /* Gracefull shutdown (byte boundaries) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001434 status = Read16_0(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1435 if (status < 0)
1436 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001437 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001438 status = Write16_0(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1439 if (status < 0)
1440 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001441
1442 /* Suppress MCLK during absence of data */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001443 status = Read16_0(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1444 if (status < 0)
1445 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001446 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001447 status = Write16_0(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1448 if (status < 0)
1449 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001450 } while (0);
1451 return status;
1452}
1453
1454static int scu_command(struct drxk_state *state,
1455 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001456 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001457{
1458#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1459#error DRXK register mapping no longer compatible with this routine!
1460#endif
1461 u16 curCmd = 0;
1462 int status;
1463 unsigned long end;
1464
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001465 dprintk(1, "\n");
1466
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001467 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1468 ((resultLen > 0) && (result == NULL)))
1469 return -1;
1470
1471 mutex_lock(&state->mutex);
1472 do {
1473 /* assume that the command register is ready
1474 since it is checked afterwards */
1475 u8 buffer[34];
1476 int cnt = 0, ii;
1477
Oliver Endrissebc7de22011-07-03 13:49:44 -03001478 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001479 buffer[cnt++] = (parameter[ii] & 0xFF);
1480 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1481 }
1482 buffer[cnt++] = (cmd & 0xFF);
1483 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1484
1485 WriteBlock(state, SCU_RAM_PARAM_0__A -
Oliver Endrissebc7de22011-07-03 13:49:44 -03001486 (parameterLen - 1), cnt, buffer, 0x00);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001487 /* Wait until SCU has processed command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001488 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001489 do {
1490 msleep(1);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001491 status = Read16_0(state, SCU_RAM_COMMAND__A, &curCmd);
1492 if (status < 0)
1493 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001494 } while (!(curCmd == DRX_SCU_READY)
1495 && (time_is_after_jiffies(end)));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001496 if (curCmd != DRX_SCU_READY) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001497 printk(KERN_ERR "drxk: SCU not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001498 mutex_unlock(&state->mutex);
1499 return -1;
1500 }
1501 /* read results */
1502 if ((resultLen > 0) && (result != NULL)) {
1503 s16 err;
1504 int ii;
1505
Oliver Endrissebc7de22011-07-03 13:49:44 -03001506 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001507 status = Read16_0(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
1508 if (status < 0)
1509 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001510 }
1511
1512 /* Check if an error was reported by SCU */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001513 err = (s16) result[0];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001514
1515 /* check a few fixed error codes */
1516 if (err == SCU_RESULT_UNKSTD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001517 printk(KERN_ERR "drxk: SCU_RESULT_UNKSTD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001518 mutex_unlock(&state->mutex);
1519 return -1;
1520 } else if (err == SCU_RESULT_UNKCMD) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001521 printk(KERN_ERR "drxk: SCU_RESULT_UNKCMD\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001522 mutex_unlock(&state->mutex);
1523 return -1;
1524 }
1525 /* here it is assumed that negative means error,
1526 and positive no error */
1527 else if (err < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001528 printk(KERN_ERR "drxk: %s ERROR\n", __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001529 mutex_unlock(&state->mutex);
1530 return -1;
1531 }
1532 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001533 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001534 mutex_unlock(&state->mutex);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001535 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001536 printk(KERN_ERR "drxk: %s: status = %d\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001537
1538 return status;
1539}
1540
1541static int SetIqmAf(struct drxk_state *state, bool active)
1542{
1543 u16 data = 0;
1544 int status;
1545
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001546 dprintk(1, "\n");
1547
Oliver Endrissebc7de22011-07-03 13:49:44 -03001548 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001549 /* Configure IQM */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001550 status = Read16_0(state, IQM_AF_STDBY__A, &data);
1551 if (status < 0)
1552 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001553 if (!active) {
1554 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1555 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1556 | IQM_AF_STDBY_STDBY_PD_STANDBY
1557 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
Oliver Endrissebc7de22011-07-03 13:49:44 -03001558 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1559 } else { /* active */
1560
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001561 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1562 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1563 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1564 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1565 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
Oliver Endrissebc7de22011-07-03 13:49:44 -03001566 );
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001567 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001568 status = Write16_0(state, IQM_AF_STDBY__A, data);
1569 if (status < 0)
1570 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001571 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001572 return status;
1573}
1574
Oliver Endrissebc7de22011-07-03 13:49:44 -03001575static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001576{
1577 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001578 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001579
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001580 dprintk(1, "\n");
1581
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001582 /* Check arguments */
1583 if (mode == NULL)
1584 return -1;
1585
1586 switch (*mode) {
1587 case DRX_POWER_UP:
1588 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1589 break;
1590 case DRXK_POWER_DOWN_OFDM:
1591 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1592 break;
1593 case DRXK_POWER_DOWN_CORE:
1594 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1595 break;
1596 case DRXK_POWER_DOWN_PLL:
1597 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1598 break;
1599 case DRX_POWER_DOWN:
1600 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1601 break;
1602 default:
1603 /* Unknow sleep mode */
1604 return -1;
1605 break;
1606 }
1607
1608 /* If already in requested power mode, do nothing */
1609 if (state->m_currentPowerMode == *mode)
1610 return 0;
1611
1612 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001613 if (state->m_currentPowerMode != DRX_POWER_UP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001614 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001615 status = PowerUpDevice(state);
1616 if (status < 0)
1617 break;
1618 status = DVBTEnableOFDMTokenRing(state, true);
1619 if (status < 0)
1620 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001621 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001622 }
1623
1624 if (*mode == DRX_POWER_UP) {
1625 /* Restore analog & pin configuartion */
1626 } else {
1627 /* Power down to requested mode */
1628 /* Backup some register settings */
1629 /* Set pins with possible pull-ups connected
1630 to them in input mode */
1631 /* Analog power down */
1632 /* ADC power down */
1633 /* Power down device */
1634 /* stop all comm_exec */
1635 /* Stop and power down previous standard */
1636 do {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001637 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001638 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001639 status = MPEGTSStop(state);
1640 if (status < 0)
1641 break;
1642 status = PowerDownDVBT(state, false);
1643 if (status < 0)
1644 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001645 break;
1646 case OM_QAM_ITU_A:
1647 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001648 status = MPEGTSStop(state);
1649 if (status < 0)
1650 break;
1651 status = PowerDownQAM(state);
1652 if (status < 0)
1653 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001654 break;
1655 default:
1656 break;
1657 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001658 status = DVBTEnableOFDMTokenRing(state, false);
1659 if (status < 0)
1660 break;
1661 status = Write16_0(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1662 if (status < 0)
1663 break;
1664 status = Write16_0(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1665 if (status < 0)
1666 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001667
Oliver Endrissebc7de22011-07-03 13:49:44 -03001668 if (*mode != DRXK_POWER_DOWN_OFDM) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001669 state->m_HICfgCtrl |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03001670 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001671 status = HI_CfgCommand(state);
1672 if (status < 0)
1673 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001674 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001675 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001676 }
1677 state->m_currentPowerMode = *mode;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001678 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001679}
1680
1681static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1682{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001683 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001684 u16 cmdResult = 0;
1685 u16 data = 0;
1686 int status;
1687
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001688 dprintk(1, "\n");
1689
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001690 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001691 status = Read16_0(state, SCU_COMM_EXEC__A, &data);
1692 if (status < 0)
1693 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001694 if (data == SCU_COMM_EXEC_ACTIVE) {
1695 /* Send OFDM stop command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001696 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
1697 if (status < 0)
1698 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001699 /* Send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001700 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1701 if (status < 0)
1702 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001703 }
1704
1705 /* Reset datapath for OFDM, processors first */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001706 status = Write16_0(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1707 if (status < 0)
1708 break;
1709 status = Write16_0(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1710 if (status < 0)
1711 break;
1712 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1713 if (status < 0)
1714 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001715
1716 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001717 status = SetIqmAf(state, false);
1718 if (status < 0)
1719 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001720
1721 /* powerdown to OFDM mode */
1722 if (setPowerMode) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001723 status = CtrlPowerMode(state, &powerMode);
1724 if (status < 0)
1725 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001726 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001727 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001728 return status;
1729}
1730
Oliver Endrissebc7de22011-07-03 13:49:44 -03001731static int SetOperationMode(struct drxk_state *state,
1732 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001733{
1734 int status = 0;
1735
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001736 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001737 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001738 Stop and power down previous standard
1739 TODO investigate total power down instead of partial
1740 power down depending on "previous" standard.
1741 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001742 do {
1743 /* disable HW lock indicator */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001744 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1745 if (status < 0)
1746 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001747
1748 if (state->m_OperationMode != oMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001749 switch (state->m_OperationMode) {
1750 /* OM_NONE was added for start up */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001751 case OM_NONE:
1752 break;
1753 case OM_DVBT:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001754 status = MPEGTSStop(state);
1755 if (status < 0)
1756 break;
1757 status = PowerDownDVBT(state, true);
1758 if (status < 0)
1759 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001760 state->m_OperationMode = OM_NONE;
1761 break;
1762 case OM_QAM_ITU_B:
1763 status = -1;
1764 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001765 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001766 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001767 status = MPEGTSStop(state);
1768 if (status < 0)
1769 break;
1770 status = PowerDownQAM(state);
1771 if (status < 0)
1772 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001773 state->m_OperationMode = OM_NONE;
1774 break;
1775 default:
1776 status = -1;
1777 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001778 status = status;
1779 if (status < 0)
1780 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001781
1782 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001783 Power up new standard
1784 */
1785 switch (oMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001786 case OM_DVBT:
1787 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001788 status = SetDVBTStandard(state, oMode);
1789 if (status < 0)
1790 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001791 break;
1792 case OM_QAM_ITU_B:
1793 status = -1;
1794 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001795 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001796 case OM_QAM_ITU_C:
1797 state->m_OperationMode = oMode;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001798 status = SetQAMStandard(state, oMode);
1799 if (status < 0)
1800 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001801 break;
1802 default:
1803 status = -1;
1804 }
1805 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001806 status = status;
1807 if (status < 0)
1808 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001809 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001810 return 0;
1811}
1812
1813static int Start(struct drxk_state *state, s32 offsetFreq,
1814 s32 IntermediateFrequency)
1815{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001816 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001817
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001818 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001819 do {
1820 u16 IFreqkHz;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001821 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001822
1823 if (state->m_DrxkState != DRXK_STOPPED &&
1824 state->m_DrxkState != DRXK_DTV_STARTED) {
1825 status = -1;
1826 break;
1827 }
1828 state->m_bMirrorFreqSpect =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001829 (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001830
1831 if (IntermediateFrequency < 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001832 state->m_bMirrorFreqSpect =
1833 !state->m_bMirrorFreqSpect;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001834 IntermediateFrequency = -IntermediateFrequency;
1835 }
1836
Oliver Endrissebc7de22011-07-03 13:49:44 -03001837 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001838 case OM_QAM_ITU_A:
1839 case OM_QAM_ITU_C:
1840 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001841 status = SetQAM(state, IFreqkHz, OffsetkHz);
1842 if (status < 0)
1843 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001844 state->m_DrxkState = DRXK_DTV_STARTED;
1845 break;
1846 case OM_DVBT:
1847 IFreqkHz = (IntermediateFrequency / 1000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001848 status = MPEGTSStop(state);
1849 if (status < 0)
1850 break;
1851 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1852 if (status < 0)
1853 break;
1854 status = DVBTStart(state);
1855 if (status < 0)
1856 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001857 state->m_DrxkState = DRXK_DTV_STARTED;
1858 break;
1859 default:
1860 break;
1861 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03001862 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001863 return status;
1864}
1865
1866static int ShutDown(struct drxk_state *state)
1867{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001868 dprintk(1, "\n");
1869
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001870 MPEGTSStop(state);
1871 return 0;
1872}
1873
Oliver Endrissebc7de22011-07-03 13:49:44 -03001874static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1875 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001876{
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001877 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001878
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001879 dprintk(1, "\n");
1880
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001881 if (pLockStatus == NULL)
1882 return -1;
1883
1884 *pLockStatus = NOT_LOCKED;
1885
1886 /* define the SCU command code */
1887 switch (state->m_OperationMode) {
1888 case OM_QAM_ITU_A:
1889 case OM_QAM_ITU_B:
1890 case OM_QAM_ITU_C:
1891 status = GetQAMLockStatus(state, pLockStatus);
1892 break;
1893 case OM_DVBT:
1894 status = GetDVBTLockStatus(state, pLockStatus);
1895 break;
1896 default:
1897 break;
1898 }
1899 return status;
1900}
1901
1902static int MPEGTSStart(struct drxk_state *state)
1903{
1904 int status = 0;
1905
1906 u16 fecOcSncMode = 0;
1907
1908 do {
1909 /* Allow OC to sync again */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001910 status = Read16_0(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1911 if (status < 0)
1912 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001913 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001914 status = Write16_0(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1915 if (status < 0)
1916 break;
1917 status = Write16_0(state, FEC_OC_SNC_UNLOCK__A, 1);
1918 if (status < 0)
1919 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001920 } while (0);
1921 return status;
1922}
1923
1924static int MPEGTSDtoInit(struct drxk_state *state)
1925{
1926 int status = -1;
1927
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001928 dprintk(1, "\n");
1929
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001930 do {
1931 /* Rate integration settings */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001932 status = Write16_0(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1933 if (status < 0)
1934 break;
1935 status = Write16_0(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1936 if (status < 0)
1937 break;
1938 status = Write16_0(state, FEC_OC_RCN_GAIN__A, 0x000A);
1939 if (status < 0)
1940 break;
1941 status = Write16_0(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1942 if (status < 0)
1943 break;
1944 status = Write16_0(state, FEC_OC_AVR_PARM_B__A, 0x0006);
1945 if (status < 0)
1946 break;
1947 status = Write16_0(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
1948 if (status < 0)
1949 break;
1950 status = Write16_0(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
1951 if (status < 0)
1952 break;
1953 status = Write16_0(state, FEC_OC_TMD_COUNT__A, 0x03F4);
1954 if (status < 0)
1955 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001956
1957 /* Additional configuration */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001958 status = Write16_0(state, FEC_OC_OCR_INVERT__A, 0);
1959 if (status < 0)
1960 break;
1961 status = Write16_0(state, FEC_OC_SNC_LWM__A, 2);
1962 if (status < 0)
1963 break;
1964 status = Write16_0(state, FEC_OC_SNC_HWM__A, 12);
1965 if (status < 0)
1966 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001967 } while (0);
1968 return status;
1969}
1970
Oliver Endrissebc7de22011-07-03 13:49:44 -03001971static int MPEGTSDtoSetup(struct drxk_state *state,
1972 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001973{
1974 int status = -1;
1975
Oliver Endrissebc7de22011-07-03 13:49:44 -03001976 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
1977 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
1978 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
1979 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
1980 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
1981 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
1982 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001983 u16 fecOcTmdMode = 0;
1984 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001985 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001986 bool staticCLK = false;
1987
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001988 dprintk(1, "\n");
1989
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001990 do {
1991 /* Check insertion of the Reed-Solomon parity bytes */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001992 status = Read16_0(state, FEC_OC_MODE__A, &fecOcRegMode);
1993 if (status < 0)
1994 break;
1995 status = Read16_0(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
1996 if (status < 0)
1997 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001998 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001999 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2000 if (state->m_insertRSByte == true) {
2001 /* enable parity symbol forward */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002002 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002003 /* MVAL disable during parity bytes */
2004 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2005 /* TS burst length to 204 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002006 fecOcDtoBurstLen = 204;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002007 }
2008
2009 /* Check serial or parrallel output */
2010 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2011 if (state->m_enableParallel == false) {
2012 /* MPEG data output is serial -> set ipr_mode[0] */
2013 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2014 }
2015
2016 switch (oMode) {
2017 case OM_DVBT:
2018 maxBitRate = state->m_DVBTBitrate;
2019 fecOcTmdMode = 3;
2020 fecOcRcnCtlRate = 0xC00000;
2021 staticCLK = state->m_DVBTStaticCLK;
2022 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002023 case OM_QAM_ITU_A: /* fallthrough */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002024 case OM_QAM_ITU_C:
2025 fecOcTmdMode = 0x0004;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002026 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002027 maxBitRate = state->m_DVBCBitrate;
2028 staticCLK = state->m_DVBCStaticCLK;
2029 break;
2030 default:
2031 status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002032 } /* switch (standard) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002033 status = status;
2034 if (status < 0)
2035 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002036
2037 /* Configure DTO's */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002038 if (staticCLK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002039 u32 bitRate = 0;
2040
2041 /* Rational DTO for MCLK source (static MCLK rate),
2042 Dynamic DTO for optimal grouping
2043 (avoid intra-packet gaps),
2044 DTO offset enable to sync TS burst with MSTRT */
2045 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2046 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2047 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2048 FEC_OC_FCT_MODE_VIRT_ENA__M);
2049
2050 /* Check user defined bitrate */
2051 bitRate = maxBitRate;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002052 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002053 bitRate = 75900000UL;
2054 }
2055 /* Rational DTO period:
2056 dto_period = (Fsys / bitrate) - 2
2057
2058 Result should be floored,
2059 to make sure >= requested bitrate
Oliver Endrissebc7de22011-07-03 13:49:44 -03002060 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002061 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2062 * 1000) / bitRate);
2063 if (fecOcDtoPeriod <= 2)
2064 fecOcDtoPeriod = 0;
2065 else
2066 fecOcDtoPeriod -= 2;
2067 fecOcTmdIntUpdRate = 8;
2068 } else {
2069 /* (commonAttr->staticCLK == false) => dynamic mode */
2070 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2071 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2072 fecOcTmdIntUpdRate = 5;
2073 }
2074
2075 /* Write appropriate registers with requested configuration */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002076 status = Write16_0(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2077 if (status < 0)
2078 break;
2079 status = Write16_0(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2080 if (status < 0)
2081 break;
2082 status = Write16_0(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2083 if (status < 0)
2084 break;
2085 status = Write16_0(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2086 if (status < 0)
2087 break;
2088 status = Write16_0(state, FEC_OC_MODE__A, fecOcRegMode);
2089 if (status < 0)
2090 break;
2091 status = Write16_0(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2092 if (status < 0)
2093 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002094
2095 /* Rate integration settings */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002096 status = Write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate, 0);
2097 if (status < 0)
2098 break;
2099 status = Write16_0(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2100 if (status < 0)
2101 break;
2102 status = Write16_0(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2103 if (status < 0)
2104 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002105 } while (0);
2106 return status;
2107}
2108
2109static int MPEGTSConfigurePolarity(struct drxk_state *state)
2110{
2111 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002112 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002113
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002114 dprintk(1, "\n");
2115
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002116 /* Data mask for the output data byte */
2117 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002118 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2119 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2120 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2121 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002122
2123 /* Control selective inversion of output bits */
2124 fecOcRegIprInvert &= (~(InvertDataMask));
2125 if (state->m_invertDATA == true)
2126 fecOcRegIprInvert |= InvertDataMask;
2127 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2128 if (state->m_invertERR == true)
2129 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2130 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2131 if (state->m_invertSTR == true)
2132 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2133 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2134 if (state->m_invertVAL == true)
2135 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2136 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2137 if (state->m_invertCLK == true)
2138 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002139 status = Write16_0(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002140 return status;
2141}
2142
2143#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2144
2145static int SetAgcRf(struct drxk_state *state,
2146 struct SCfgAgc *pAgcCfg, bool isDTV)
2147{
2148 int status = 0;
2149 struct SCfgAgc *pIfAgcSettings;
2150
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002151 dprintk(1, "\n");
2152
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002153 if (pAgcCfg == NULL)
2154 return -1;
2155
2156 do {
2157 u16 data = 0;
2158
2159 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002160 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002161
2162 /* Enable RF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002163 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2164 if (status < 0)
2165 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002166 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002167 status = Write16_0(state, IQM_AF_STDBY__A, data);
2168 if (status < 0)
2169 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002170
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002171 status = Read16(state, SCU_RAM_AGC_CONFIG__A, &data, 0);
2172 if (status < 0)
2173 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002174
2175 /* Enable SCU RF AGC loop */
2176 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2177
2178 /* Polarity */
2179 if (state->m_RfAgcPol)
2180 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2181 else
2182 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002183 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2184 if (status < 0)
2185 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002186
2187 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002188 status = Read16(state, SCU_RAM_AGC_KI_RED__A, &data, 0);
2189 if (status < 0)
2190 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002191
2192 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2193 data |= (~(pAgcCfg->speed <<
2194 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2195 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2196
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002197 status = Write16_0(state, SCU_RAM_AGC_KI_RED__A, data);
2198 if (status < 0)
2199 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002200
2201 if (IsDVBT(state))
2202 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2203 else if (IsQAM(state))
2204 pIfAgcSettings = &state->m_qamIfAgcCfg;
2205 else
2206 pIfAgcSettings = &state->m_atvIfAgcCfg;
2207 if (pIfAgcSettings == NULL)
2208 return -1;
2209
2210 /* Set TOP, only if IF-AGC is in AUTO mode */
2211 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002212 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
2213 if (status < 0)
2214 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002215
2216 /* Cut-Off current */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002217 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2218 if (status < 0)
2219 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002220
2221 /* Max. output level */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002222 status = Write16_0(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2223 if (status < 0)
2224 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002225
2226 break;
2227
2228 case DRXK_AGC_CTRL_USER:
2229 /* Enable RF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002230 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2231 if (status < 0)
2232 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002233 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002234 status = Write16_0(state, IQM_AF_STDBY__A, data);
2235 if (status < 0)
2236 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002237
2238 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002239 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2240 if (status < 0)
2241 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002242 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2243 if (state->m_RfAgcPol)
2244 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2245 else
2246 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002247 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2248 if (status < 0)
2249 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002250
2251 /* SCU c.o.c. to 0, enabling full control range */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002252 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2253 if (status < 0)
2254 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002255
2256 /* Write value to output pin */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002257 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2258 if (status < 0)
2259 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002260 break;
2261
Oliver Endrissebc7de22011-07-03 13:49:44 -03002262 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002263 /* Disable RF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002264 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2265 if (status < 0)
2266 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002267 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002268 status = Write16_0(state, IQM_AF_STDBY__A, data);
2269 if (status < 0)
2270 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002271
2272 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002273 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2274 if (status < 0)
2275 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002276 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002277 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2278 if (status < 0)
2279 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002280 break;
2281
2282 default:
2283 return -1;
2284
Oliver Endrissebc7de22011-07-03 13:49:44 -03002285 } /* switch (agcsettings->ctrlMode) */
2286 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002287 return status;
2288}
2289
2290#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2291
Oliver Endrissebc7de22011-07-03 13:49:44 -03002292static int SetAgcIf(struct drxk_state *state,
2293 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002294{
2295 u16 data = 0;
2296 int status = 0;
2297 struct SCfgAgc *pRfAgcSettings;
2298
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002299 dprintk(1, "\n");
2300
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002301 do {
2302 switch (pAgcCfg->ctrlMode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002303 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002304
2305 /* Enable IF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002306 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2307 if (status < 0)
2308 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002309 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002310 status = Write16_0(state, IQM_AF_STDBY__A, data);
2311 if (status < 0)
2312 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002313
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002314 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2315 if (status < 0)
2316 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002317
2318 /* Enable SCU IF AGC loop */
2319 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2320
2321 /* Polarity */
2322 if (state->m_IfAgcPol)
2323 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2324 else
2325 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002326 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2327 if (status < 0)
2328 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002329
2330 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002331 status = Read16_0(state, SCU_RAM_AGC_KI_RED__A, &data);
2332 if (status < 0)
2333 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002334 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2335 data |= (~(pAgcCfg->speed <<
2336 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2337 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2338
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002339 status = Write16_0(state, SCU_RAM_AGC_KI_RED__A, data);
2340 if (status < 0)
2341 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002342
2343 if (IsQAM(state))
2344 pRfAgcSettings = &state->m_qamRfAgcCfg;
2345 else
2346 pRfAgcSettings = &state->m_atvRfAgcCfg;
2347 if (pRfAgcSettings == NULL)
2348 return -1;
2349 /* Restore TOP */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002350 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2351 if (status < 0)
2352 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002353 break;
2354
Oliver Endrissebc7de22011-07-03 13:49:44 -03002355 case DRXK_AGC_CTRL_USER:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002356
2357 /* Enable IF AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002358 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2359 if (status < 0)
2360 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002361 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002362 status = Write16_0(state, IQM_AF_STDBY__A, data);
2363 if (status < 0)
2364 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002365
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002366 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2367 if (status < 0)
2368 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002369
2370 /* Disable SCU IF AGC loop */
2371 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2372
2373 /* Polarity */
2374 if (state->m_IfAgcPol)
2375 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2376 else
2377 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002378 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2379 if (status < 0)
2380 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002381
2382 /* Write value to output pin */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002383 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2384 if (status < 0)
2385 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002386 break;
2387
Oliver Endrissebc7de22011-07-03 13:49:44 -03002388 case DRXK_AGC_CTRL_OFF:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002389
2390 /* Disable If AGC DAC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002391 status = Read16_0(state, IQM_AF_STDBY__A, &data);
2392 if (status < 0)
2393 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002394 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002395 status = Write16_0(state, IQM_AF_STDBY__A, data);
2396 if (status < 0)
2397 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002398
2399 /* Disable SCU IF AGC loop */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002400 status = Read16_0(state, SCU_RAM_AGC_CONFIG__A, &data);
2401 if (status < 0)
2402 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002403 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002404 status = Write16_0(state, SCU_RAM_AGC_CONFIG__A, data);
2405 if (status < 0)
2406 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002407 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002408 } /* switch (agcSettingsIf->ctrlMode) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002409
2410 /* always set the top to support
2411 configurations without if-loop */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002412 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2413 if (status < 0)
2414 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002415
2416
Oliver Endrissebc7de22011-07-03 13:49:44 -03002417 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002418 return status;
2419}
2420
2421static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2422{
2423 u16 agcDacLvl;
2424 int status = Read16_0(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2425
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002426 dprintk(1, "\n");
2427
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002428 *pValue = 0;
2429
Oliver Endrissebc7de22011-07-03 13:49:44 -03002430 if (status == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002431 u16 Level = 0;
2432 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2433 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2434 if (Level < 14000)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002435 *pValue = (14000 - Level) / 4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002436 else
2437 *pValue = 0;
2438 }
2439 return status;
2440}
2441
Oliver Endrissebc7de22011-07-03 13:49:44 -03002442static int GetQAMSignalToNoise(struct drxk_state *state,
2443 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002444{
2445 int status = 0;
2446
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002447 dprintk(1, "\n");
2448
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002449 do {
2450 /* MER calculation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002451 u16 qamSlErrPower = 0; /* accum. error between
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002452 raw and sliced symbols */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002453 u32 qamSlSigPower = 0; /* used for MER, depends of
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002454 QAM constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002455 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002456
2457 /* get the register value needed for MER */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002458 status = Read16_0(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2459 if (status < 0)
2460 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002461
Oliver Endrissebc7de22011-07-03 13:49:44 -03002462 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002463 case QAM_16:
2464 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2465 break;
2466 case QAM_32:
2467 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2468 break;
2469 case QAM_64:
2470 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2471 break;
2472 case QAM_128:
2473 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2474 break;
2475 default:
2476 case QAM_256:
2477 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2478 break;
2479 }
2480
2481 if (qamSlErrPower > 0) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002482 qamSlMer = Log10Times100(qamSlSigPower) -
2483 Log10Times100((u32) qamSlErrPower);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002484 }
2485 *pSignalToNoise = qamSlMer;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002486 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002487 return status;
2488}
2489
Oliver Endrissebc7de22011-07-03 13:49:44 -03002490static int GetDVBTSignalToNoise(struct drxk_state *state,
2491 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002492{
2493 int status = 0;
2494
Oliver Endrissebc7de22011-07-03 13:49:44 -03002495 u16 regData = 0;
2496 u32 EqRegTdSqrErrI = 0;
2497 u32 EqRegTdSqrErrQ = 0;
2498 u16 EqRegTdSqrErrExp = 0;
2499 u16 EqRegTdTpsPwrOfs = 0;
2500 u16 EqRegTdReqSmbCnt = 0;
2501 u32 tpsCnt = 0;
2502 u32 SqrErrIQ = 0;
2503 u32 a = 0;
2504 u32 b = 0;
2505 u32 c = 0;
2506 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002507 u16 transmissionParams = 0;
2508
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002509 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002510 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002511 status = Read16_0(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2512 if (status < 0)
2513 break;
2514 status = Read16_0(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2515 if (status < 0)
2516 break;
2517 status = Read16_0(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2518 if (status < 0)
2519 break;
2520 status = Read16_0(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2521 if (status < 0)
2522 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002523 /* Extend SQR_ERR_I operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002524 EqRegTdSqrErrI = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002525 if ((EqRegTdSqrErrExp > 11) &&
2526 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2527 EqRegTdSqrErrI += 0x00010000UL;
2528 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002529 status = Read16_0(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2530 if (status < 0)
2531 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002532 /* Extend SQR_ERR_Q operational range */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002533 EqRegTdSqrErrQ = (u32) regData;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002534 if ((EqRegTdSqrErrExp > 11) &&
2535 (EqRegTdSqrErrQ < 0x00000FFFUL))
2536 EqRegTdSqrErrQ += 0x00010000UL;
2537
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002538 status = Read16_0(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2539 if (status < 0)
2540 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002541
2542 /* Check input data for MER */
2543
2544 /* MER calculation (in 0.1 dB) without math.h */
2545 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2546 iMER = 0;
2547 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2548 /* No error at all, this must be the HW reset value
2549 * Apparently no first measurement yet
2550 * Set MER to 0.0 */
2551 iMER = 0;
2552 } else {
2553 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
Oliver Endrissebc7de22011-07-03 13:49:44 -03002554 EqRegTdSqrErrExp;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002555 if ((transmissionParams &
2556 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2557 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2558 tpsCnt = 17;
2559 else
2560 tpsCnt = 68;
2561
2562 /* IMER = 100 * log10 (x)
2563 where x = (EqRegTdTpsPwrOfs^2 *
2564 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2565
2566 => IMER = a + b -c
2567 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2568 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2569 c = 100 * log10 (SqrErrIQ)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002570 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002571
2572 /* log(x) x = 9bits * 9bits->18 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002573 a = Log10Times100(EqRegTdTpsPwrOfs *
2574 EqRegTdTpsPwrOfs);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002575 /* log(x) x = 16bits * 7bits->23 bits */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002576 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002577 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2578 c = Log10Times100(SqrErrIQ);
2579
2580 iMER = a + b;
2581 /* No negative MER, clip to zero */
2582 if (iMER > c)
2583 iMER -= c;
2584 else
2585 iMER = 0;
2586 }
2587 *pSignalToNoise = iMER;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002588 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002589
2590 return status;
2591}
2592
2593static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2594{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002595 dprintk(1, "\n");
2596
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002597 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002598 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002599 case OM_DVBT:
2600 return GetDVBTSignalToNoise(state, pSignalToNoise);
2601 case OM_QAM_ITU_A:
2602 case OM_QAM_ITU_C:
2603 return GetQAMSignalToNoise(state, pSignalToNoise);
2604 default:
2605 break;
2606 }
2607 return 0;
2608}
2609
2610#if 0
2611static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2612{
2613 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2614 int status = 0;
2615
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002616 dprintk(1, "\n");
2617
Oliver Endrissebc7de22011-07-03 13:49:44 -03002618 static s32 QE_SN[] = {
2619 51, /* QPSK 1/2 */
2620 69, /* QPSK 2/3 */
2621 79, /* QPSK 3/4 */
2622 89, /* QPSK 5/6 */
2623 97, /* QPSK 7/8 */
2624 108, /* 16-QAM 1/2 */
2625 131, /* 16-QAM 2/3 */
2626 146, /* 16-QAM 3/4 */
2627 156, /* 16-QAM 5/6 */
2628 160, /* 16-QAM 7/8 */
2629 165, /* 64-QAM 1/2 */
2630 187, /* 64-QAM 2/3 */
2631 202, /* 64-QAM 3/4 */
2632 216, /* 64-QAM 5/6 */
2633 225, /* 64-QAM 7/8 */
2634 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002635
2636 *pQuality = 0;
2637
2638 do {
2639 s32 SignalToNoise = 0;
2640 u16 Constellation = 0;
2641 u16 CodeRate = 0;
2642 u32 SignalToNoiseRel;
2643 u32 BERQuality;
2644
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002645 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2646 if (status < 0)
2647 break;
2648 status = Read16_0(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
2649 if (status < 0)
2650 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002651 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2652
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002653 status = Read16_0(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
2654 if (status < 0)
2655 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002656 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2657
2658 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2659 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2660 break;
2661 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002662 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002663 BERQuality = 100;
2664
Oliver Endrissebc7de22011-07-03 13:49:44 -03002665 if (SignalToNoiseRel < -70)
2666 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002667 else if (SignalToNoiseRel < 30)
2668 *pQuality = ((SignalToNoiseRel + 70) *
2669 BERQuality) / 100;
2670 else
2671 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002672 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002673 return 0;
2674};
2675
Oliver Endrissebc7de22011-07-03 13:49:44 -03002676static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002677{
2678 int status = 0;
2679 *pQuality = 0;
2680
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002681 dprintk(1, "\n");
2682
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002683 do {
2684 u32 SignalToNoise = 0;
2685 u32 BERQuality = 100;
2686 u32 SignalToNoiseRel = 0;
2687
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002688 status = GetQAMSignalToNoise(state, &SignalToNoise);
2689 if (status < 0)
2690 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002691
Oliver Endrissebc7de22011-07-03 13:49:44 -03002692 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002693 case QAM_16:
2694 SignalToNoiseRel = SignalToNoise - 200;
2695 break;
2696 case QAM_32:
2697 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002698 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002699 case QAM_64:
2700 SignalToNoiseRel = SignalToNoise - 260;
2701 break;
2702 case QAM_128:
2703 SignalToNoiseRel = SignalToNoise - 290;
2704 break;
2705 default:
2706 case QAM_256:
2707 SignalToNoiseRel = SignalToNoise - 320;
2708 break;
2709 }
2710
2711 if (SignalToNoiseRel < -70)
2712 *pQuality = 0;
2713 else if (SignalToNoiseRel < 30)
2714 *pQuality = ((SignalToNoiseRel + 70) *
2715 BERQuality) / 100;
2716 else
2717 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002718 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002719
2720 return status;
2721}
2722
2723static int GetQuality(struct drxk_state *state, s32 *pQuality)
2724{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002725 dprintk(1, "\n");
2726
Oliver Endrissebc7de22011-07-03 13:49:44 -03002727 switch (state->m_OperationMode) {
2728 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002729 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002730 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002731 return GetDVBCQuality(state, pQuality);
2732 default:
2733 break;
2734 }
2735
2736 return 0;
2737}
2738#endif
2739
2740/* Free data ram in SIO HI */
2741#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2742#define SIO_HI_RA_RAM_USR_END__A 0x420060
2743
2744#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2745#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2746#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2747#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2748
2749#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2750#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2751#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2752
2753static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2754{
2755 int status;
2756
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002757 dprintk(1, "\n");
2758
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002759 if (state->m_DrxkState == DRXK_UNINITIALIZED)
2760 return -1;
2761 if (state->m_DrxkState == DRXK_POWERED_DOWN)
2762 return -1;
2763
2764 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002765 status = Write16_0(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2766 if (status < 0)
2767 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002768 if (bEnableBridge) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002769 status = Write16_0(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
2770 if (status < 0)
2771 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002772 } else {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002773 status = Write16_0(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2774 if (status < 0)
2775 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002776 }
2777
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002778 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2779 if (status < 0)
2780 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002781 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002782 return status;
2783}
2784
Oliver Endrissebc7de22011-07-03 13:49:44 -03002785static int SetPreSaw(struct drxk_state *state,
2786 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002787{
2788 int status;
2789
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002790 dprintk(1, "\n");
2791
Oliver Endrissebc7de22011-07-03 13:49:44 -03002792 if ((pPreSawCfg == NULL)
2793 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002794 return -1;
2795
2796 status = Write16_0(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
2797 return status;
2798}
2799
2800static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002801 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002802{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002803 u16 blStatus = 0;
2804 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2805 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2806 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002807 unsigned long end;
2808
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002809 dprintk(1, "\n");
2810
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002811 mutex_lock(&state->mutex);
2812 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002813 status = Write16_0(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2814 if (status < 0)
2815 break;
2816 status = Write16_0(state, SIO_BL_TGT_HDR__A, blockbank);
2817 if (status < 0)
2818 break;
2819 status = Write16_0(state, SIO_BL_TGT_ADDR__A, offset);
2820 if (status < 0)
2821 break;
2822 status = Write16_0(state, SIO_BL_SRC_ADDR__A, romOffset);
2823 if (status < 0)
2824 break;
2825 status = Write16_0(state, SIO_BL_SRC_LEN__A, nrOfElements);
2826 if (status < 0)
2827 break;
2828 status = Write16_0(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2829 if (status < 0)
2830 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002831
Oliver Endrissebc7de22011-07-03 13:49:44 -03002832 end = jiffies + msecs_to_jiffies(timeOut);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002833 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002834 status = Read16_0(state, SIO_BL_STATUS__A, &blStatus);
2835 if (status < 0)
2836 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002837 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002838 if (blStatus == 0x1) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03002839 printk(KERN_ERR "drxk: SIO not ready\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002840 mutex_unlock(&state->mutex);
2841 return -1;
2842 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03002843 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002844 mutex_unlock(&state->mutex);
2845 return status;
2846
2847}
2848
Oliver Endrissebc7de22011-07-03 13:49:44 -03002849static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002850{
2851 u16 data = 0;
2852 int status;
2853
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002854 dprintk(1, "\n");
2855
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002856 do {
2857 /* Start measurement */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002858 status = Write16_0(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2859 if (status < 0)
2860 break;
2861 status = Write16_0(state, IQM_AF_START_LOCK__A, 1);
2862 if (status < 0)
2863 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002864
2865 *count = 0;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002866 status = Read16_0(state, IQM_AF_PHASE0__A, &data);
2867 if (status < 0)
2868 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002869 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002870 *count = *count + 1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002871 status = Read16_0(state, IQM_AF_PHASE1__A, &data);
2872 if (status < 0)
2873 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002874 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002875 *count = *count + 1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002876 status = Read16_0(state, IQM_AF_PHASE2__A, &data);
2877 if (status < 0)
2878 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002879 if (data == 127)
Oliver Endrissebc7de22011-07-03 13:49:44 -03002880 *count = *count + 1;
2881 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002882 return status;
2883}
2884
2885static int ADCSynchronization(struct drxk_state *state)
2886{
2887 u16 count = 0;
2888 int status;
2889
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002890 dprintk(1, "\n");
2891
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002892 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002893 status = ADCSyncMeasurement(state, &count);
2894 if (status < 0)
2895 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002896
Oliver Endrissebc7de22011-07-03 13:49:44 -03002897 if (count == 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002898 /* Try sampling on a diffrent edge */
2899 u16 clkNeg = 0;
2900
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002901 status = Read16_0(state, IQM_AF_CLKNEG__A, &clkNeg);
2902 if (status < 0)
2903 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002904 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002905 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2906 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2907 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002908 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002909 } else {
2910 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2911 clkNeg |=
Oliver Endrissebc7de22011-07-03 13:49:44 -03002912 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002913 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002914 status = Write16_0(state, IQM_AF_CLKNEG__A, clkNeg);
2915 if (status < 0)
2916 break;
2917 status = ADCSyncMeasurement(state, &count);
2918 if (status < 0)
2919 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002920 }
2921
2922 if (count < 2)
2923 status = -1;
2924 } while (0);
2925 return status;
2926}
2927
2928static int SetFrequencyShifter(struct drxk_state *state,
2929 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002930 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002931{
2932 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002933 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002934 u32 fmFrequencyShift = 0;
2935 bool tunerMirror = !state->m_bMirrorFreqSpect;
2936 u32 adcFreq;
2937 bool adcFlip;
2938 int status;
2939 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002940 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002941 u32 frequencyShift;
2942 bool imageToSelect;
2943
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002944 dprintk(1, "\n");
2945
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002946 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03002947 Program frequency shifter
2948 No need to account for mirroring on RF
2949 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002950 if (isDTV) {
2951 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
2952 (state->m_OperationMode == OM_QAM_ITU_C) ||
2953 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03002954 selectPosImage = true;
2955 else
2956 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002957 }
2958 if (tunerMirror)
2959 /* tuner doesn't mirror */
2960 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03002961 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002962 else
2963 /* tuner mirrors */
2964 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002965 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002966 if (ifFreqActual > samplingFrequency / 2) {
2967 /* adc mirrors */
2968 adcFreq = samplingFrequency - ifFreqActual;
2969 adcFlip = true;
2970 } else {
2971 /* adc doesn't mirror */
2972 adcFreq = ifFreqActual;
2973 adcFlip = false;
2974 }
2975
2976 frequencyShift = adcFreq;
2977 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03002978 adcFlip ^ selectPosImage;
2979 state->m_IqmFsRateOfs =
2980 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002981
2982 if (imageToSelect)
2983 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
2984
2985 /* Program frequency shifter with tuner offset compensation */
2986 /* frequencyShift += tunerFreqOffset; TODO */
Oliver Endrissebc7de22011-07-03 13:49:44 -03002987 status = Write32(state, IQM_FS_RATE_OFS_LO__A,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002988 state->m_IqmFsRateOfs, 0);
2989 return status;
2990}
2991
2992static int InitAGC(struct drxk_state *state, bool isDTV)
2993{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002994 u16 ingainTgt = 0;
2995 u16 ingainTgtMin = 0;
2996 u16 ingainTgtMax = 0;
2997 u16 clpCyclen = 0;
2998 u16 clpSumMin = 0;
2999 u16 clpDirTo = 0;
3000 u16 snsSumMin = 0;
3001 u16 snsSumMax = 0;
3002 u16 clpSumMax = 0;
3003 u16 snsDirTo = 0;
3004 u16 kiInnergainMin = 0;
3005 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003006 u16 ifIaccuHiTgtMin = 0;
3007 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003008 u16 data = 0;
3009 u16 fastClpCtrlDelay = 0;
3010 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003011 int status = 0;
3012
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003013 dprintk(1, "\n");
3014
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003015 do {
3016 /* Common settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003017 snsSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003018 ifIaccuHiTgtMin = 2047;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003019 clpCyclen = 500;
3020 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003021
3022 if (IsQAM(state)) {
3023 /* Standard specific settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003024 clpSumMin = 8;
3025 clpDirTo = (u16) -9;
3026 clpCtrlMode = 0;
3027 snsSumMin = 8;
3028 snsDirTo = (u16) -9;
3029 kiInnergainMin = (u16) -1030;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003030 } else
3031 status = -1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003032 status = (status);
3033 if (status < 0)
3034 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003035 if (IsQAM(state)) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003036 ifIaccuHiTgtMax = 0x2380;
3037 ifIaccuHiTgt = 0x2380;
3038 ingainTgtMin = 0x0511;
3039 ingainTgt = 0x0511;
3040 ingainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003041 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003042 state->m_qamIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003043 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -03003044 ifIaccuHiTgtMax = 0x1200;
3045 ifIaccuHiTgt = 0x1200;
3046 ingainTgtMin = 13424;
3047 ingainTgt = 13424;
3048 ingainTgtMax = 30000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003049 fastClpCtrlDelay =
Oliver Endrissebc7de22011-07-03 13:49:44 -03003050 state->m_dvbtIfAgcCfg.FastClipCtrlDelay;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003051 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003052 status = Write16_0(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3053 if (status < 0)
3054 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003055
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003056 status = Write16_0(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3057 if (status < 0)
3058 break;
3059 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3060 if (status < 0)
3061 break;
3062 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3063 if (status < 0)
3064 break;
3065 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3066 if (status < 0)
3067 break;
3068 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3069 if (status < 0)
3070 break;
3071 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3072 if (status < 0)
3073 break;
3074 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3075 if (status < 0)
3076 break;
3077 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3078 if (status < 0)
3079 break;
3080 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3081 if (status < 0)
3082 break;
3083 status = Write16_0(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3084 if (status < 0)
3085 break;
3086 status = Write16_0(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3087 if (status < 0)
3088 break;
3089 status = Write16_0(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3090 if (status < 0)
3091 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003092
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003093 status = Write16_0(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3094 if (status < 0)
3095 break;
3096 status = Write16_0(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3097 if (status < 0)
3098 break;
3099 status = Write16_0(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3100 if (status < 0)
3101 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003102
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003103 status = Write16_0(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3104 if (status < 0)
3105 break;
3106 status = Write16_0(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3107 if (status < 0)
3108 break;
3109 status = Write16_0(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3110 if (status < 0)
3111 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003112
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003113 status = Write16_0(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3114 if (status < 0)
3115 break;
3116 status = Write16_0(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3117 if (status < 0)
3118 break;
3119 status = Write16_0(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3120 if (status < 0)
3121 break;
3122 status = Write16_0(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3123 if (status < 0)
3124 break;
3125 status = Write16_0(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3126 if (status < 0)
3127 break;
3128 status = Write16_0(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3129 if (status < 0)
3130 break;
3131 status = Write16_0(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3132 if (status < 0)
3133 break;
3134 status = Write16_0(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3135 if (status < 0)
3136 break;
3137 status = Write16_0(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3138 if (status < 0)
3139 break;
3140 status = Write16_0(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3141 if (status < 0)
3142 break;
3143 status = Write16_0(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3144 if (status < 0)
3145 break;
3146 status = Write16_0(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3147 if (status < 0)
3148 break;
3149 status = Write16_0(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3150 if (status < 0)
3151 break;
3152 status = Write16_0(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3153 if (status < 0)
3154 break;
3155 status = Write16_0(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3156 if (status < 0)
3157 break;
3158 status = Write16_0(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3159 if (status < 0)
3160 break;
3161 status = Write16_0(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3162 if (status < 0)
3163 break;
3164 status = Write16_0(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3165 if (status < 0)
3166 break;
3167 status = Write16_0(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3168 if (status < 0)
3169 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003170
3171 /* Initialize inner-loop KI gain factors */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003172 status = Read16_0(state, SCU_RAM_AGC_KI__A, &data);
3173 if (status < 0)
3174 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003175 if (IsQAM(state)) {
3176 data = 0x0657;
3177 data &= ~SCU_RAM_AGC_KI_RF__M;
3178 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3179 data &= ~SCU_RAM_AGC_KI_IF__M;
3180 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3181 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003182 status = Write16_0(state, SCU_RAM_AGC_KI__A, data);
3183 if (status < 0)
3184 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003185 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003186 return status;
3187}
3188
Oliver Endrissebc7de22011-07-03 13:49:44 -03003189static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003190{
3191 int status;
3192
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003193 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003194 do {
3195 if (packetErr == NULL) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003196 status = Write16_0(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3197 if (status < 0)
3198 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003199 } else {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003200 status = Read16_0(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3201 if (status < 0)
3202 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003203 }
3204 } while (0);
3205 return status;
3206}
3207
3208static int DVBTScCommand(struct drxk_state *state,
3209 u16 cmd, u16 subcmd,
3210 u16 param0, u16 param1, u16 param2,
3211 u16 param3, u16 param4)
3212{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003213 u16 curCmd = 0;
3214 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003215 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003216 u16 scExec = 0;
3217 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003218
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003219 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003220 status = Read16_0(state, OFDM_SC_COMM_EXEC__A, &scExec);
3221 if (scExec != 1) {
3222 /* SC is not running */
3223 return -1;
3224 }
3225
3226 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003227 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003228 do {
3229 msleep(1);
3230 status = Read16_0(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
3231 retryCnt++;
3232 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
3233 if (retryCnt >= DRXK_MAX_RETRIES)
3234 return -1;
3235 /* Write sub-command */
3236 switch (cmd) {
3237 /* All commands using sub-cmd */
3238 case OFDM_SC_RA_RAM_CMD_PROC_START:
3239 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3240 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003241 status =
3242 Write16_0(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003243 break;
3244 default:
3245 /* Do nothing */
3246 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003247 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003248
3249 /* Write needed parameters and the command */
3250 switch (cmd) {
3251 /* All commands using 5 parameters */
3252 /* All commands using 4 parameters */
3253 /* All commands using 3 parameters */
3254 /* All commands using 2 parameters */
3255 case OFDM_SC_RA_RAM_CMD_PROC_START:
3256 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3257 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003258 status =
3259 Write16_0(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003260 /* All commands using 1 parameters */
3261 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3262 case OFDM_SC_RA_RAM_CMD_USER_IO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003263 status =
3264 Write16_0(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003265 /* All commands using 0 parameters */
3266 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3267 case OFDM_SC_RA_RAM_CMD_NULL:
3268 /* Write command */
3269 status = Write16_0(state, OFDM_SC_RA_RAM_CMD__A, cmd);
3270 break;
3271 default:
3272 /* Unknown command */
3273 return -EINVAL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003274 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003275
3276 /* Wait until sc is ready processing command */
3277 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003278 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003279 msleep(1);
3280 status = Read16_0(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
3281 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003282 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003283 if (retryCnt >= DRXK_MAX_RETRIES)
3284 return -1;
3285
3286 /* Check for illegal cmd */
3287 status = Read16_0(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003288 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003289 /* illegal command */
3290 return -EINVAL;
3291 }
3292
3293 /* Retreive results parameters from SC */
3294 switch (cmd) {
3295 /* All commands yielding 5 results */
3296 /* All commands yielding 4 results */
3297 /* All commands yielding 3 results */
3298 /* All commands yielding 2 results */
3299 /* All commands yielding 1 result */
3300 case OFDM_SC_RA_RAM_CMD_USER_IO:
3301 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003302 status =
3303 Read16_0(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003304 /* All commands yielding 0 results */
3305 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3306 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3307 case OFDM_SC_RA_RAM_CMD_PROC_START:
3308 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3309 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3310 case OFDM_SC_RA_RAM_CMD_NULL:
3311 break;
3312 default:
3313 /* Unknown command */
3314 return -EINVAL;
3315 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003316 } /* switch (cmd->cmd) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003317 return status;
3318}
3319
Oliver Endrissebc7de22011-07-03 13:49:44 -03003320static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003321{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003322 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003323 int status;
3324
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003325 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003326 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003327 status = CtrlPowerMode(state, &powerMode);
3328 if (status < 0)
3329 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003330 } while (0);
3331 return status;
3332}
3333
Oliver Endrissebc7de22011-07-03 13:49:44 -03003334static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003335{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003336 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003337
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003338 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003339 if (*enabled == true)
3340 status = Write16_0(state, IQM_CF_BYPASSDET__A, 0);
3341 else
3342 status = Write16_0(state, IQM_CF_BYPASSDET__A, 1);
3343
3344 return status;
3345}
3346
3347#define DEFAULT_FR_THRES_8K 4000
3348static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3349{
3350
3351 int status;
3352
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003353 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003354 if (*enabled == true) {
3355 /* write mask to 1 */
3356 status = Write16_0(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
3357 DEFAULT_FR_THRES_8K);
3358 } else {
3359 /* write mask to 0 */
3360 status = Write16_0(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
3361 }
3362
3363 return status;
3364}
3365
3366static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3367 struct DRXKCfgDvbtEchoThres_t *echoThres)
3368{
3369 u16 data = 0;
3370 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003371
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003372 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003373 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003374 status = Read16_0(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3375 if (status < 0)
3376 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003377
Oliver Endrissebc7de22011-07-03 13:49:44 -03003378 switch (echoThres->fftMode) {
3379 case DRX_FFTMODE_2K:
3380 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3381 data |=
3382 ((echoThres->threshold <<
3383 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3384 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3385 break;
3386 case DRX_FFTMODE_8K:
3387 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3388 data |=
3389 ((echoThres->threshold <<
3390 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3391 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3392 break;
3393 default:
3394 return -1;
3395 break;
3396 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003397
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003398 status = Write16_0(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3399 if (status < 0)
3400 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003401 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003402
Oliver Endrissebc7de22011-07-03 13:49:44 -03003403 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003404}
3405
3406static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003407 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003408{
3409 int status;
3410
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003411 dprintk(1, "\n");
3412
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003413 switch (*speed) {
3414 case DRXK_DVBT_SQI_SPEED_FAST:
3415 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3416 case DRXK_DVBT_SQI_SPEED_SLOW:
3417 break;
3418 default:
3419 return -EINVAL;
3420 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03003421 status = Write16_0(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
3422 (u16) *speed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003423 return status;
3424}
3425
3426/*============================================================================*/
3427
3428/**
3429* \brief Activate DVBT specific presets
3430* \param demod instance of demodulator.
3431* \return DRXStatus_t.
3432*
3433* Called in DVBTSetStandard
3434*
3435*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003436static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003437{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003438 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003439
Oliver Endrissebc7de22011-07-03 13:49:44 -03003440 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3441 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003442
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003443 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003444 do {
3445 bool setincenable = false;
3446 bool setfrenable = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003447 status = DVBTCtrlSetIncEnable(state, &setincenable);
3448 if (status < 0)
3449 break;
3450 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3451 if (status < 0)
3452 break;
3453 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3454 if (status < 0)
3455 break;
3456 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3457 if (status < 0)
3458 break;
3459 status = Write16_0(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3460 if (status < 0)
3461 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003462 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003463
Oliver Endrissebc7de22011-07-03 13:49:44 -03003464 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003465}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003466
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003467/*============================================================================*/
3468
3469/**
3470* \brief Initialize channelswitch-independent settings for DVBT.
3471* \param demod instance of demodulator.
3472* \return DRXStatus_t.
3473*
3474* For ROM code channel filter taps are loaded from the bootloader. For microcode
3475* the DVB-T taps from the drxk_filters.h are used.
3476*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003477static int SetDVBTStandard(struct drxk_state *state,
3478 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003479{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003480 u16 cmdResult = 0;
3481 u16 data = 0;
3482 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003483
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003484 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003485
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003486 PowerUpDVBT(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003487 do {
3488 /* added antenna switch */
3489 SwitchAntennaToDVBT(state);
3490 /* send OFDM reset command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003491 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
3492 if (status < 0)
3493 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003494
3495 /* send OFDM setenv command */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003496 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3497 if (status < 0)
3498 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003499
3500 /* reset datapath for OFDM, processors first */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003501 status = Write16_0(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3502 if (status < 0)
3503 break;
3504 status = Write16_0(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3505 if (status < 0)
3506 break;
3507 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3508 if (status < 0)
3509 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003510
3511 /* IQM setup */
3512 /* synchronize on ofdstate->m_festart */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003513 status = Write16_0(state, IQM_AF_UPD_SEL__A, 1);
3514 if (status < 0)
3515 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003516 /* window size for clipping ADC detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003517 status = Write16_0(state, IQM_AF_CLP_LEN__A, 0);
3518 if (status < 0)
3519 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003520 /* window size for for sense pre-SAW detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003521 status = Write16_0(state, IQM_AF_SNS_LEN__A, 0);
3522 if (status < 0)
3523 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003524 /* sense threshold for sense pre-SAW detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003525 status = Write16_0(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3526 if (status < 0)
3527 break;
3528 status = SetIqmAf(state, true);
3529 if (status < 0)
3530 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003531
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003532 status = Write16_0(state, IQM_AF_AGC_RF__A, 0);
3533 if (status < 0)
3534 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003535
3536 /* Impulse noise cruncher setup */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003537 status = Write16_0(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3538 if (status < 0)
3539 break;
3540 status = Write16_0(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3541 if (status < 0)
3542 break;
3543 status = Write16_0(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3544 if (status < 0)
3545 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003546
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003547 status = Write16_0(state, IQM_RC_STRETCH__A, 16);
3548 if (status < 0)
3549 break;
3550 status = Write16_0(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3551 if (status < 0)
3552 break;
3553 status = Write16_0(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3554 if (status < 0)
3555 break;
3556 status = Write16_0(state, IQM_CF_SCALE__A, 1600);
3557 if (status < 0)
3558 break;
3559 status = Write16_0(state, IQM_CF_SCALE_SH__A, 0);
3560 if (status < 0)
3561 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003562
3563 /* virtual clipping threshold for clipping ADC detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003564 status = Write16_0(state, IQM_AF_CLP_TH__A, 448);
3565 if (status < 0)
3566 break;
3567 status = Write16_0(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3568 if (status < 0)
3569 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003570
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003571 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3572 if (status < 0)
3573 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003574
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003575 status = Write16_0(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3576 if (status < 0)
3577 break;
3578 status = Write16_0(state, IQM_CF_POW_MEAS_LEN__A, 2);
3579 if (status < 0)
3580 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003581 /* enable power measurement interrupt */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003582 status = Write16_0(state, IQM_CF_COMM_INT_MSK__A, 1);
3583 if (status < 0)
3584 break;
3585 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3586 if (status < 0)
3587 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003588
3589 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003590 status = ADCSynchronization(state);
3591 if (status < 0)
3592 break;
3593 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3594 if (status < 0)
3595 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003596
3597 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003598 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3599 if (status < 0)
3600 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003601
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003602 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3603 if (status < 0)
3604 break;
3605 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3606 if (status < 0)
3607 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003608
3609 /* Set Noise Estimation notch width and enable DC fix */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003610 status = Read16_0(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3611 if (status < 0)
3612 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003613 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003614 status = Write16_0(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3615 if (status < 0)
3616 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003617
3618 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003619 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3620 if (status < 0)
3621 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003622
Oliver Endrissebc7de22011-07-03 13:49:44 -03003623 if (!state->m_DRXK_A3_ROM_CODE) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003624 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003625 status = Write16_0(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3626 if (status < 0)
3627 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003628 }
3629
3630 /* OFDM_SC setup */
3631#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003632 status = Write16_0(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3633 if (status < 0)
3634 break;
3635 status = Write16_0(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3636 if (status < 0)
3637 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003638#endif
3639
3640 /* FEC setup */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003641 status = Write16_0(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3642 if (status < 0)
3643 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003644
3645
3646#ifdef COMPILE_FOR_NONRT
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003647 status = Write16_0(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3648 if (status < 0)
3649 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003650#else
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003651 status = Write16_0(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3652 if (status < 0)
3653 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003654#endif
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003655 status = Write16_0(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3656 if (status < 0)
3657 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003658
3659 /* Setup MPEG bus */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003660 status = MPEGTSDtoSetup(state, OM_DVBT);
3661 if (status < 0)
3662 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003663 /* Set DVBT Presets */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003664 status = DVBTActivatePresets(state);
3665 if (status < 0)
3666 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003667
3668 } while (0);
3669
Oliver Endrissebc7de22011-07-03 13:49:44 -03003670 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003671 printk(KERN_ERR "drxk: %s status - %08x\n", __func__, status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003672
3673 return status;
3674}
3675
3676/*============================================================================*/
3677/**
3678* \brief Start dvbt demodulating for channel.
3679* \param demod instance of demodulator.
3680* \return DRXStatus_t.
3681*/
3682static int DVBTStart(struct drxk_state *state)
3683{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003684 u16 param1;
3685 int status;
3686 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003687
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003688 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003689 /* Start correct processes to get in lock */
3690 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
3691 do {
3692 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003693 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3694 if (status < 0)
3695 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003696 /* Start FEC OC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003697 status = MPEGTSStart(state);
3698 if (status < 0)
3699 break;
3700 status = Write16_0(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3701 if (status < 0)
3702 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003703 } while (0);
3704 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003705}
3706
3707
3708/*============================================================================*/
3709
3710/**
3711* \brief Set up dvbt demodulator for channel.
3712* \param demod instance of demodulator.
3713* \return DRXStatus_t.
3714* // original DVBTSetChannel()
3715*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003716static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3717 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003718{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003719 u16 cmdResult = 0;
3720 u16 transmissionParams = 0;
3721 u16 operationMode = 0;
3722 u32 iqmRcRateOfs = 0;
3723 u32 bandwidth = 0;
3724 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003725 int status;
3726
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003727 dprintk(1, "\n");
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03003728 /* printk(KERN_DEBUG "drxk: %s IF =%d, TFO = %d\n", __func__, IntermediateFreqkHz, tunerFreqOffset); */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003729 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003730 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3731 if (status < 0)
3732 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003733
3734 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003735 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3736 if (status < 0)
3737 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003738
3739 /* Stop processors */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003740 status = Write16_0(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3741 if (status < 0)
3742 break;
3743 status = Write16_0(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3744 if (status < 0)
3745 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003746
3747 /* Mandatory fix, always stop CP, required to set spl offset back to
3748 hardware default (is set to 0 by ucode during pilot detection */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003749 status = Write16_0(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3750 if (status < 0)
3751 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003752
3753 /*== Write channel settings to device =====================================*/
3754
3755 /* mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003756 switch (state->param.u.ofdm.transmission_mode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003757 case TRANSMISSION_MODE_AUTO:
3758 default:
3759 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3760 /* fall through , try first guess DRX_FFTMODE_8K */
3761 case TRANSMISSION_MODE_8K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003762 transmissionParams |=
3763 OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003764 break;
3765 case TRANSMISSION_MODE_2K:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003766 transmissionParams |=
3767 OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003768 break;
3769 }
3770
3771 /* guard */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003772 switch (state->param.u.ofdm.guard_interval) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003773 default:
3774 case GUARD_INTERVAL_AUTO:
3775 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3776 /* fall through , try first guess DRX_GUARD_1DIV4 */
3777 case GUARD_INTERVAL_1_4:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003778 transmissionParams |=
3779 OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003780 break;
3781 case GUARD_INTERVAL_1_32:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003782 transmissionParams |=
3783 OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003784 break;
3785 case GUARD_INTERVAL_1_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003786 transmissionParams |=
3787 OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003788 break;
3789 case GUARD_INTERVAL_1_8:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003790 transmissionParams |=
3791 OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003792 break;
3793 }
3794
3795 /* hierarchy */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003796 switch (state->param.u.ofdm.hierarchy_information) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003797 case HIERARCHY_AUTO:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003798 case HIERARCHY_NONE:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003799 default:
3800 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3801 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003802 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3803 /* break; */
3804 case HIERARCHY_1:
3805 transmissionParams |=
3806 OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003807 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003808 case HIERARCHY_2:
3809 transmissionParams |=
3810 OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003811 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003812 case HIERARCHY_4:
3813 transmissionParams |=
3814 OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003815 break;
3816 }
3817
3818
3819 /* constellation */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003820 switch (state->param.u.ofdm.constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003821 case QAM_AUTO:
3822 default:
3823 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3824 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3825 case QAM_64:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003826 transmissionParams |=
3827 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003828 break;
3829 case QPSK:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003830 transmissionParams |=
3831 OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003832 break;
3833 case QAM_16:
Oliver Endrissebc7de22011-07-03 13:49:44 -03003834 transmissionParams |=
3835 OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003836 break;
3837 }
3838#if 0
Oliver Endrissebc7de22011-07-03 13:49:44 -03003839 /* No hierachical channels support in BDA */
3840 /* Priority (only for hierarchical channels) */
3841 switch (channel->priority) {
3842 case DRX_PRIORITY_LOW:
3843 transmissionParams |=
3844 OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3845 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3846 OFDM_EC_SB_PRIOR_LO);
3847 break;
3848 case DRX_PRIORITY_HIGH:
3849 transmissionParams |=
3850 OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3851 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3852 OFDM_EC_SB_PRIOR_HI));
3853 break;
3854 case DRX_PRIORITY_UNKNOWN: /* fall through */
3855 default:
3856 return DRX_STS_INVALID_ARG;
3857 break;
3858 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003859#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03003860 /* Set Priorty high */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003861 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003862 status = Write16_0(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3863 if (status < 0)
3864 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003865#endif
3866
3867 /* coderate */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003868 switch (state->param.u.ofdm.code_rate_HP) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003869 case FEC_AUTO:
3870 default:
3871 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3872 /* fall through , try first guess DRX_CODERATE_2DIV3 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003873 case FEC_2_3:
3874 transmissionParams |=
3875 OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003876 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003877 case FEC_1_2:
3878 transmissionParams |=
3879 OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003880 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003881 case FEC_3_4:
3882 transmissionParams |=
3883 OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003884 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003885 case FEC_5_6:
3886 transmissionParams |=
3887 OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003888 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003889 case FEC_7_8:
3890 transmissionParams |=
3891 OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003892 break;
3893 }
3894
3895 /* SAW filter selection: normaly not necesarry, but if wanted
3896 the application can select a SAW filter via the driver by using UIOs */
3897 /* First determine real bandwidth (Hz) */
3898 /* Also set delay for impulse noise cruncher */
3899 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3900 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3901 functions */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003902 switch (state->param.u.ofdm.bandwidth) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003903 case BANDWIDTH_AUTO:
3904 case BANDWIDTH_8_MHZ:
3905 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003906 status = Write16_0(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
3907 if (status < 0)
3908 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003909 /* cochannel protection for PAL 8 MHz */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003910 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3911 if (status < 0)
3912 break;
3913 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3914 if (status < 0)
3915 break;
3916 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3917 if (status < 0)
3918 break;
3919 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3920 if (status < 0)
3921 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003922 break;
3923 case BANDWIDTH_7_MHZ:
3924 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003925 status = Write16_0(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3926 if (status < 0)
3927 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003928 /* cochannel protection for PAL 7 MHz */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003929 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3930 if (status < 0)
3931 break;
3932 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3933 if (status < 0)
3934 break;
3935 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3936 if (status < 0)
3937 break;
3938 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3939 if (status < 0)
3940 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003941 break;
3942 case BANDWIDTH_6_MHZ:
3943 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003944 status = Write16_0(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3945 if (status < 0)
3946 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003947 /* cochannel protection for NTSC 6 MHz */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003948 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3949 if (status < 0)
3950 break;
3951 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3952 if (status < 0)
3953 break;
3954 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3955 if (status < 0)
3956 break;
3957 status = Write16_0(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3958 if (status < 0)
3959 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003960 break;
Mauro Carvalho Chehabe16cede2011-07-03 18:18:14 -03003961 default:
3962 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003963 }
3964
Oliver Endrissebc7de22011-07-03 13:49:44 -03003965 if (iqmRcRateOfs == 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003966 /* Now compute IQM_RC_RATE_OFS
3967 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3968 =>
3969 ((SysFreq / BandWidth) * (2^21)) - (2^23)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003970 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003971 /* (SysFreq / BandWidth) * (2^28) */
3972 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
3973 => assert(MAX(sysClk) < 16*MIN(bandwidth))
3974 => assert(109714272 > 48000000) = true so Frac 28 can be used */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003975 iqmRcRateOfs = Frac28a((u32)
3976 ((state->m_sysClockFreq *
3977 1000) / 3), bandwidth);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003978 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
3979 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003980 iqmRcRateOfs += 0x80L;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003981 iqmRcRateOfs = iqmRcRateOfs >> 7;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003982 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003983 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003984 }
3985
Oliver Endrissebc7de22011-07-03 13:49:44 -03003986 iqmRcRateOfs &=
3987 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
3988 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003989 status = Write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs, 0);
3990 if (status < 0)
3991 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003992
3993 /* Bandwidth setting done */
3994
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003995#if 0
3996 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
3997 if (status < 0)
3998 break;
3999#endif
4000 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4001 if (status < 0)
4002 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004003
4004 /*== Start SC, write channel settings to SC ===============================*/
4005
4006 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004007 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4008 if (status < 0)
4009 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004010
4011 /* Enable SC after setting all other parameters */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004012 status = Write16_0(state, OFDM_SC_COMM_STATE__A, 0);
4013 if (status < 0)
4014 break;
4015 status = Write16_0(state, OFDM_SC_COMM_EXEC__A, 1);
4016 if (status < 0)
4017 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004018
4019
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004020 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4021 if (status < 0)
4022 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004023
4024 /* Write SC parameter registers, set all AUTO flags in operation mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004025 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4026 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4027 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4028 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4029 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4030 status =
4031 DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4032 0, transmissionParams, param1, 0, 0, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004033 if (!state->m_DRXK_A3_ROM_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004034 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4035 if (status < 0)
4036 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004037
Oliver Endrissebc7de22011-07-03 13:49:44 -03004038 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004039
4040 return status;
4041}
4042
4043
4044/*============================================================================*/
4045
4046/**
4047* \brief Retreive lock status .
4048* \param demod Pointer to demodulator instance.
4049* \param lockStat Pointer to lock status structure.
4050* \return DRXStatus_t.
4051*
4052*/
4053static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4054{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004055 int status;
4056 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4057 OFDM_SC_RA_RAM_LOCK_FEC__M);
4058 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4059 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004060
Oliver Endrissebc7de22011-07-03 13:49:44 -03004061 u16 ScRaRamLock = 0;
4062 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004063
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004064 dprintk(1, "\n");
4065
Oliver Endrissebc7de22011-07-03 13:49:44 -03004066 /* driver 0.9.0 */
4067 /* Check if SC is running */
4068 status = Read16_0(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
4069 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP) {
4070 /* SC not active; return DRX_NOT_LOCKED */
4071 *pLockStatus = NOT_LOCKED;
4072 return status;
4073 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004074
Oliver Endrissebc7de22011-07-03 13:49:44 -03004075 status = Read16_0(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004076
Oliver Endrissebc7de22011-07-03 13:49:44 -03004077 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4078 *pLockStatus = MPEG_LOCK;
4079 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4080 *pLockStatus = FEC_LOCK;
4081 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4082 *pLockStatus = DEMOD_LOCK;
4083 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4084 *pLockStatus = NEVER_LOCK;
4085 else
4086 *pLockStatus = NOT_LOCKED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004087
Oliver Endrissebc7de22011-07-03 13:49:44 -03004088 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004089}
4090
Oliver Endrissebc7de22011-07-03 13:49:44 -03004091static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004092{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004093 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
4094 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004095
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004096 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004097 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004098 status = CtrlPowerMode(state, &powerMode);
4099 if (status < 0)
4100 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004101
Oliver Endrissebc7de22011-07-03 13:49:44 -03004102 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004103
Oliver Endrissebc7de22011-07-03 13:49:44 -03004104 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004105}
4106
4107
Oliver Endrissebc7de22011-07-03 13:49:44 -03004108/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004109static int PowerDownQAM(struct drxk_state *state)
4110{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004111 u16 data = 0;
4112 u16 cmdResult;
4113 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004114
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004115 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004116 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004117 status = Read16_0(state, SCU_COMM_EXEC__A, &data);
4118 if (status < 0)
4119 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004120 if (data == SCU_COMM_EXEC_ACTIVE) {
4121 /*
4122 STOP demodulator
4123 QAM and HW blocks
4124 */
4125 /* stop all comstate->m_exec */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004126 status = Write16_0(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
4127 if (status < 0)
4128 break;
4129 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
4130 if (status < 0)
4131 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004132 }
4133 /* powerdown AFE */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004134 status = SetIqmAf(state, false);
4135 if (status < 0)
4136 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004137 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004138
Oliver Endrissebc7de22011-07-03 13:49:44 -03004139 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004140}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004141
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004142/*============================================================================*/
4143
4144/**
4145* \brief Setup of the QAM Measurement intervals for signal quality
4146* \param demod instance of demod.
4147* \param constellation current constellation.
4148* \return DRXStatus_t.
4149*
4150* NOTE:
4151* Take into account that for certain settings the errorcounters can overflow.
4152* The implementation does not check this.
4153*
4154*/
4155static int SetQAMMeasurement(struct drxk_state *state,
4156 enum EDrxkConstellation constellation,
4157 u32 symbolRate)
4158{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004159 u32 fecBitsDesired = 0; /* BER accounting period */
4160 u32 fecRsPeriodTotal = 0; /* Total period */
4161 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4162 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004163 int status = 0;
4164
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004165 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004166
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004167 fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004168 do {
4169
4170 /* fecBitsDesired = symbolRate [kHz] *
4171 FrameLenght [ms] *
4172 (constellation + 1) *
4173 SyncLoss (== 1) *
4174 ViterbiLoss (==1)
Oliver Endrissebc7de22011-07-03 13:49:44 -03004175 */
4176 switch (constellation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004177 case DRX_CONSTELLATION_QAM16:
4178 fecBitsDesired = 4 * symbolRate;
4179 break;
4180 case DRX_CONSTELLATION_QAM32:
4181 fecBitsDesired = 5 * symbolRate;
4182 break;
4183 case DRX_CONSTELLATION_QAM64:
4184 fecBitsDesired = 6 * symbolRate;
4185 break;
4186 case DRX_CONSTELLATION_QAM128:
4187 fecBitsDesired = 7 * symbolRate;
4188 break;
4189 case DRX_CONSTELLATION_QAM256:
4190 fecBitsDesired = 8 * symbolRate;
4191 break;
4192 default:
4193 status = -EINVAL;
4194 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004195 status = status;
4196 if (status < 0)
4197 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004198
Oliver Endrissebc7de22011-07-03 13:49:44 -03004199 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4200 fecBitsDesired *= 500; /* meas. period [ms] */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004201
4202 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4203 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
Oliver Endrissebc7de22011-07-03 13:49:44 -03004204 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004205
4206 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4207 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4208 if (fecRsPrescale == 0) {
4209 /* Divide by zero (though impossible) */
4210 status = -1;
4211 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004212 status = status;
4213 if (status < 0)
4214 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004215 fecRsPeriod =
4216 ((u16) fecRsPeriodTotal +
4217 (fecRsPrescale >> 1)) / fecRsPrescale;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004218
4219 /* write corresponding registers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004220 status = Write16_0(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4221 if (status < 0)
4222 break;
4223 status = Write16_0(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4224 if (status < 0)
4225 break;
4226 status = Write16_0(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4227 if (status < 0)
4228 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004229
4230 } while (0);
4231
Oliver Endrissebc7de22011-07-03 13:49:44 -03004232 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03004233 printk(KERN_ERR "drxk: %s: status - %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004234
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004235 return status;
4236}
4237
Oliver Endrissebc7de22011-07-03 13:49:44 -03004238static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004239{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004240 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004241
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004242 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004243 do {
4244 /* QAM Equalizer Setup */
4245 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004246 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4247 if (status < 0)
4248 break;
4249 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4250 if (status < 0)
4251 break;
4252 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4253 if (status < 0)
4254 break;
4255 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4256 if (status < 0)
4257 break;
4258 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4259 if (status < 0)
4260 break;
4261 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4262 if (status < 0)
4263 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004264 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004265 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 2);
4266 if (status < 0)
4267 break;
4268 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 2);
4269 if (status < 0)
4270 break;
4271 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 2);
4272 if (status < 0)
4273 break;
4274 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 2);
4275 if (status < 0)
4276 break;
4277 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 2);
4278 if (status < 0)
4279 break;
4280 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4281 if (status < 0)
4282 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004283
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004284 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 5);
4285 if (status < 0)
4286 break;
4287 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 4);
4288 if (status < 0)
4289 break;
4290 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4291 if (status < 0)
4292 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004293
Oliver Endrissebc7de22011-07-03 13:49:44 -03004294 /* QAM Slicer Settings */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004295 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4296 if (status < 0)
4297 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004298
Oliver Endrissebc7de22011-07-03 13:49:44 -03004299 /* QAM Loop Controller Coeficients */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004300 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4301 if (status < 0)
4302 break;
4303 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4304 if (status < 0)
4305 break;
4306 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4307 if (status < 0)
4308 break;
4309 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4310 if (status < 0)
4311 break;
4312 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4313 if (status < 0)
4314 break;
4315 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4316 if (status < 0)
4317 break;
4318 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4319 if (status < 0)
4320 break;
4321 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4322 if (status < 0)
4323 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004324
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004325 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4326 if (status < 0)
4327 break;
4328 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4329 if (status < 0)
4330 break;
4331 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4332 if (status < 0)
4333 break;
4334 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4335 if (status < 0)
4336 break;
4337 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4338 if (status < 0)
4339 break;
4340 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4341 if (status < 0)
4342 break;
4343 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4344 if (status < 0)
4345 break;
4346 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4347 if (status < 0)
4348 break;
4349 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4350 if (status < 0)
4351 break;
4352 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4353 if (status < 0)
4354 break;
4355 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4356 if (status < 0)
4357 break;
4358 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4359 if (status < 0)
4360 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004361
4362
Oliver Endrissebc7de22011-07-03 13:49:44 -03004363 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004364
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004365 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4366 if (status < 0)
4367 break;
4368 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4369 if (status < 0)
4370 break;
4371 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4372 if (status < 0)
4373 break;
4374 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4375 if (status < 0)
4376 break;
4377 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4378 if (status < 0)
4379 break;
4380 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4381 if (status < 0)
4382 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004383
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004384 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4385 if (status < 0)
4386 break;
4387 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4388 if (status < 0)
4389 break;
4390 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4391 if (status < 0)
4392 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004393
4394
Oliver Endrissebc7de22011-07-03 13:49:44 -03004395 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004396
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004397 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4398 if (status < 0)
4399 break;
4400 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4401 if (status < 0)
4402 break;
4403 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4404 if (status < 0)
4405 break;
4406 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4407 if (status < 0)
4408 break;
4409 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4410 if (status < 0)
4411 break;
4412 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4413 if (status < 0)
4414 break;
4415 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4416 if (status < 0)
4417 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004418 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004419
Oliver Endrissebc7de22011-07-03 13:49:44 -03004420 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004421}
4422
4423/*============================================================================*/
4424
4425/**
4426* \brief QAM32 specific setup
4427* \param demod instance of demod.
4428* \return DRXStatus_t.
4429*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004430static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004431{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004432 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004433
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004434 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004435 do {
4436 /* QAM Equalizer Setup */
4437 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004438 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4439 if (status < 0)
4440 break;
4441 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4442 if (status < 0)
4443 break;
4444 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4445 if (status < 0)
4446 break;
4447 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4448 if (status < 0)
4449 break;
4450 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4451 if (status < 0)
4452 break;
4453 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4454 if (status < 0)
4455 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004456
Oliver Endrissebc7de22011-07-03 13:49:44 -03004457 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004458 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 3);
4459 if (status < 0)
4460 break;
4461 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 3);
4462 if (status < 0)
4463 break;
4464 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 3);
4465 if (status < 0)
4466 break;
4467 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 3);
4468 if (status < 0)
4469 break;
4470 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 3);
4471 if (status < 0)
4472 break;
4473 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4474 if (status < 0)
4475 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004476
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004477 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 6);
4478 if (status < 0)
4479 break;
4480 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 5);
4481 if (status < 0)
4482 break;
4483 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4484 if (status < 0)
4485 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004486
Oliver Endrissebc7de22011-07-03 13:49:44 -03004487 /* QAM Slicer Settings */
4488
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004489 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4490 if (status < 0)
4491 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004492
4493
Oliver Endrissebc7de22011-07-03 13:49:44 -03004494 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004495
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004496 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4497 if (status < 0)
4498 break;
4499 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4500 if (status < 0)
4501 break;
4502 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4503 if (status < 0)
4504 break;
4505 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4506 if (status < 0)
4507 break;
4508 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4509 if (status < 0)
4510 break;
4511 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4512 if (status < 0)
4513 break;
4514 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4515 if (status < 0)
4516 break;
4517 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4518 if (status < 0)
4519 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004520
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004521 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4522 if (status < 0)
4523 break;
4524 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4525 if (status < 0)
4526 break;
4527 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4528 if (status < 0)
4529 break;
4530 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4531 if (status < 0)
4532 break;
4533 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4534 if (status < 0)
4535 break;
4536 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4537 if (status < 0)
4538 break;
4539 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4540 if (status < 0)
4541 break;
4542 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4543 if (status < 0)
4544 break;
4545 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4546 if (status < 0)
4547 break;
4548 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4549 if (status < 0)
4550 break;
4551 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4552 if (status < 0)
4553 break;
4554 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4555 if (status < 0)
4556 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004557
4558
Oliver Endrissebc7de22011-07-03 13:49:44 -03004559 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004560
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004561 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4562 if (status < 0)
4563 break;
4564 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4565 if (status < 0)
4566 break;
4567 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4568 if (status < 0)
4569 break;
4570 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4571 if (status < 0)
4572 break;
4573 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4574 if (status < 0)
4575 break;
4576 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4577 if (status < 0)
4578 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004579
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004580 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4581 if (status < 0)
4582 break;
4583 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4584 if (status < 0)
4585 break;
4586 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4587 if (status < 0)
4588 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004589
4590
Oliver Endrissebc7de22011-07-03 13:49:44 -03004591 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004592
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004593 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4594 if (status < 0)
4595 break;
4596 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4597 if (status < 0)
4598 break;
4599 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4600 if (status < 0)
4601 break;
4602 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4603 if (status < 0)
4604 break;
4605 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4606 if (status < 0)
4607 break;
4608 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4609 if (status < 0)
4610 break;
4611 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4612 if (status < 0)
4613 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004614 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004615
Oliver Endrissebc7de22011-07-03 13:49:44 -03004616 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004617}
4618
4619/*============================================================================*/
4620
4621/**
4622* \brief QAM64 specific setup
4623* \param demod instance of demod.
4624* \return DRXStatus_t.
4625*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004626static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004627{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004628 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004629
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004630 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004631 do {
4632 /* QAM Equalizer Setup */
4633 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004634 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4635 if (status < 0)
4636 break;
4637 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4638 if (status < 0)
4639 break;
4640 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4641 if (status < 0)
4642 break;
4643 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4644 if (status < 0)
4645 break;
4646 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4647 if (status < 0)
4648 break;
4649 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4650 if (status < 0)
4651 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004652
Oliver Endrissebc7de22011-07-03 13:49:44 -03004653 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004654 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 4);
4655 if (status < 0)
4656 break;
4657 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 4);
4658 if (status < 0)
4659 break;
4660 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 4);
4661 if (status < 0)
4662 break;
4663 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 4);
4664 if (status < 0)
4665 break;
4666 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 3);
4667 if (status < 0)
4668 break;
4669 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4670 if (status < 0)
4671 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004672
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004673 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 5);
4674 if (status < 0)
4675 break;
4676 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 4);
4677 if (status < 0)
4678 break;
4679 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4680 if (status < 0)
4681 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004682
4683 /* QAM Slicer Settings */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004684 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4685 if (status < 0)
4686 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004687
4688
Oliver Endrissebc7de22011-07-03 13:49:44 -03004689 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004690
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004691 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4692 if (status < 0)
4693 break;
4694 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4695 if (status < 0)
4696 break;
4697 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4698 if (status < 0)
4699 break;
4700 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4701 if (status < 0)
4702 break;
4703 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4704 if (status < 0)
4705 break;
4706 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4707 if (status < 0)
4708 break;
4709 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4710 if (status < 0)
4711 break;
4712 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4713 if (status < 0)
4714 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004715
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004716 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4717 if (status < 0)
4718 break;
4719 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4720 if (status < 0)
4721 break;
4722 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4723 if (status < 0)
4724 break;
4725 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4726 if (status < 0)
4727 break;
4728 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4729 if (status < 0)
4730 break;
4731 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4732 if (status < 0)
4733 break;
4734 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4735 if (status < 0)
4736 break;
4737 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4738 if (status < 0)
4739 break;
4740 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4741 if (status < 0)
4742 break;
4743 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4744 if (status < 0)
4745 break;
4746 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4747 if (status < 0)
4748 break;
4749 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4750 if (status < 0)
4751 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004752
4753
Oliver Endrissebc7de22011-07-03 13:49:44 -03004754 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004755
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004756 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4757 if (status < 0)
4758 break;
4759 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4760 if (status < 0)
4761 break;
4762 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4763 if (status < 0)
4764 break;
4765 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4766 if (status < 0)
4767 break;
4768 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4769 if (status < 0)
4770 break;
4771 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4772 if (status < 0)
4773 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004774
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004775 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4776 if (status < 0)
4777 break;
4778 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4779 if (status < 0)
4780 break;
4781 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4782 if (status < 0)
4783 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004784
4785
Oliver Endrissebc7de22011-07-03 13:49:44 -03004786 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004787
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004788 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4789 if (status < 0)
4790 break;
4791 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4792 if (status < 0)
4793 break;
4794 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4795 if (status < 0)
4796 break;
4797 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4798 if (status < 0)
4799 break;
4800 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4801 if (status < 0)
4802 break;
4803 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4804 if (status < 0)
4805 break;
4806 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4807 if (status < 0)
4808 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004809 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004810
Oliver Endrissebc7de22011-07-03 13:49:44 -03004811 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004812}
4813
4814/*============================================================================*/
4815
4816/**
4817* \brief QAM128 specific setup
4818* \param demod: instance of demod.
4819* \return DRXStatus_t.
4820*/
4821static int SetQAM128(struct drxk_state *state)
4822{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004823 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004824
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004825 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03004826 do {
4827 /* QAM Equalizer Setup */
4828 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004829 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4830 if (status < 0)
4831 break;
4832 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4833 if (status < 0)
4834 break;
4835 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4836 if (status < 0)
4837 break;
4838 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4839 if (status < 0)
4840 break;
4841 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4842 if (status < 0)
4843 break;
4844 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4845 if (status < 0)
4846 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004847
Oliver Endrissebc7de22011-07-03 13:49:44 -03004848 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004849 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 6);
4850 if (status < 0)
4851 break;
4852 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 6);
4853 if (status < 0)
4854 break;
4855 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 6);
4856 if (status < 0)
4857 break;
4858 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 6);
4859 if (status < 0)
4860 break;
4861 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 5);
4862 if (status < 0)
4863 break;
4864 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
4865 if (status < 0)
4866 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004867
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004868 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 6);
4869 if (status < 0)
4870 break;
4871 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 5);
4872 if (status < 0)
4873 break;
4874 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
4875 if (status < 0)
4876 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004877
4878
Oliver Endrissebc7de22011-07-03 13:49:44 -03004879 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004880
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004881 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4882 if (status < 0)
4883 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004884
4885
Oliver Endrissebc7de22011-07-03 13:49:44 -03004886 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004887
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004888 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4889 if (status < 0)
4890 break;
4891 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4892 if (status < 0)
4893 break;
4894 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4895 if (status < 0)
4896 break;
4897 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4898 if (status < 0)
4899 break;
4900 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4901 if (status < 0)
4902 break;
4903 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4904 if (status < 0)
4905 break;
4906 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4907 if (status < 0)
4908 break;
4909 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4910 if (status < 0)
4911 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004912
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004913 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4914 if (status < 0)
4915 break;
4916 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4917 if (status < 0)
4918 break;
4919 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4920 if (status < 0)
4921 break;
4922 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4923 if (status < 0)
4924 break;
4925 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4926 if (status < 0)
4927 break;
4928 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4929 if (status < 0)
4930 break;
4931 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4932 if (status < 0)
4933 break;
4934 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4935 if (status < 0)
4936 break;
4937 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4938 if (status < 0)
4939 break;
4940 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4941 if (status < 0)
4942 break;
4943 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4944 if (status < 0)
4945 break;
4946 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4947 if (status < 0)
4948 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004949
4950
Oliver Endrissebc7de22011-07-03 13:49:44 -03004951 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004952
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004953 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4954 if (status < 0)
4955 break;
4956 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4957 if (status < 0)
4958 break;
4959 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4960 if (status < 0)
4961 break;
4962 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4963 if (status < 0)
4964 break;
4965 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4966 if (status < 0)
4967 break;
4968 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4969 if (status < 0)
4970 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004971
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004972 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4973 if (status < 0)
4974 break;
4975 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
4976 if (status < 0)
4977 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004978
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004979 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
4980 if (status < 0)
4981 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004982
Oliver Endrissebc7de22011-07-03 13:49:44 -03004983 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004984
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004985 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
4986 if (status < 0)
4987 break;
4988 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
4989 if (status < 0)
4990 break;
4991 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
4992 if (status < 0)
4993 break;
4994 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
4995 if (status < 0)
4996 break;
4997 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
4998 if (status < 0)
4999 break;
5000 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5001 if (status < 0)
5002 break;
5003 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5004 if (status < 0)
5005 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005006 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005007
Oliver Endrissebc7de22011-07-03 13:49:44 -03005008 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005009}
5010
5011/*============================================================================*/
5012
5013/**
5014* \brief QAM256 specific setup
5015* \param demod: instance of demod.
5016* \return DRXStatus_t.
5017*/
5018static int SetQAM256(struct drxk_state *state)
5019{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005020 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005021
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005022 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005023 do {
5024 /* QAM Equalizer Setup */
5025 /* Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005026 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5027 if (status < 0)
5028 break;
5029 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5030 if (status < 0)
5031 break;
5032 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5033 if (status < 0)
5034 break;
5035 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5036 if (status < 0)
5037 break;
5038 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5039 if (status < 0)
5040 break;
5041 status = Write16_0(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5042 if (status < 0)
5043 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005044
Oliver Endrissebc7de22011-07-03 13:49:44 -03005045 /* Decision Feedback Equalizer */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005046 status = Write16_0(state, QAM_DQ_QUAL_FUN0__A, 8);
5047 if (status < 0)
5048 break;
5049 status = Write16_0(state, QAM_DQ_QUAL_FUN1__A, 8);
5050 if (status < 0)
5051 break;
5052 status = Write16_0(state, QAM_DQ_QUAL_FUN2__A, 8);
5053 if (status < 0)
5054 break;
5055 status = Write16_0(state, QAM_DQ_QUAL_FUN3__A, 8);
5056 if (status < 0)
5057 break;
5058 status = Write16_0(state, QAM_DQ_QUAL_FUN4__A, 6);
5059 if (status < 0)
5060 break;
5061 status = Write16_0(state, QAM_DQ_QUAL_FUN5__A, 0);
5062 if (status < 0)
5063 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005064
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005065 status = Write16_0(state, QAM_SY_SYNC_HWM__A, 5);
5066 if (status < 0)
5067 break;
5068 status = Write16_0(state, QAM_SY_SYNC_AWM__A, 4);
5069 if (status < 0)
5070 break;
5071 status = Write16_0(state, QAM_SY_SYNC_LWM__A, 3);
5072 if (status < 0)
5073 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005074
Oliver Endrissebc7de22011-07-03 13:49:44 -03005075 /* QAM Slicer Settings */
5076
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005077 status = Write16_0(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5078 if (status < 0)
5079 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005080
5081
Oliver Endrissebc7de22011-07-03 13:49:44 -03005082 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005083
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005084 status = Write16_0(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5085 if (status < 0)
5086 break;
5087 status = Write16_0(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5088 if (status < 0)
5089 break;
5090 status = Write16_0(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5091 if (status < 0)
5092 break;
5093 status = Write16_0(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5094 if (status < 0)
5095 break;
5096 status = Write16_0(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5097 if (status < 0)
5098 break;
5099 status = Write16_0(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5100 if (status < 0)
5101 break;
5102 status = Write16_0(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5103 if (status < 0)
5104 break;
5105 status = Write16_0(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5106 if (status < 0)
5107 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005108
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005109 status = Write16_0(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5110 if (status < 0)
5111 break;
5112 status = Write16_0(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5113 if (status < 0)
5114 break;
5115 status = Write16_0(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5116 if (status < 0)
5117 break;
5118 status = Write16_0(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5119 if (status < 0)
5120 break;
5121 status = Write16_0(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5122 if (status < 0)
5123 break;
5124 status = Write16_0(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5125 if (status < 0)
5126 break;
5127 status = Write16_0(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5128 if (status < 0)
5129 break;
5130 status = Write16_0(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5131 if (status < 0)
5132 break;
5133 status = Write16_0(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5134 if (status < 0)
5135 break;
5136 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5137 if (status < 0)
5138 break;
5139 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5140 if (status < 0)
5141 break;
5142 status = Write16_0(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5143 if (status < 0)
5144 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005145
5146
Oliver Endrissebc7de22011-07-03 13:49:44 -03005147 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005148
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005149 status = Write16_0(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5150 if (status < 0)
5151 break;
5152 status = Write16_0(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5153 if (status < 0)
5154 break;
5155 status = Write16_0(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5156 if (status < 0)
5157 break;
5158 status = Write16_0(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5159 if (status < 0)
5160 break;
5161 status = Write16_0(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5162 if (status < 0)
5163 break;
5164 status = Write16_0(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5165 if (status < 0)
5166 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005167
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005168 status = Write16_0(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5169 if (status < 0)
5170 break;
5171 status = Write16_0(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5172 if (status < 0)
5173 break;
5174 status = Write16_0(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5175 if (status < 0)
5176 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005177
5178
Oliver Endrissebc7de22011-07-03 13:49:44 -03005179 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005180
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005181 status = Write16_0(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5182 if (status < 0)
5183 break;
5184 status = Write16_0(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5185 if (status < 0)
5186 break;
5187 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5188 if (status < 0)
5189 break;
5190 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5191 if (status < 0)
5192 break;
5193 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5194 if (status < 0)
5195 break;
5196 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5197 if (status < 0)
5198 break;
5199 status = Write16_0(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5200 if (status < 0)
5201 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005202 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005203
Oliver Endrissebc7de22011-07-03 13:49:44 -03005204 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005205}
5206
5207
5208/*============================================================================*/
5209/**
5210* \brief Reset QAM block.
5211* \param demod: instance of demod.
5212* \param channel: pointer to channel data.
5213* \return DRXStatus_t.
5214*/
5215static int QAMResetQAM(struct drxk_state *state)
5216{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005217 int status;
5218 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005219
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005220 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005221 do {
5222 /* Stop QAM comstate->m_exec */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005223 status = Write16_0(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5224 if (status < 0)
5225 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005226
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005227 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5228 if (status < 0)
5229 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005230 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005231
Oliver Endrissebc7de22011-07-03 13:49:44 -03005232 /* All done, all OK */
5233 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005234}
5235
5236/*============================================================================*/
5237
5238/**
5239* \brief Set QAM symbolrate.
5240* \param demod: instance of demod.
5241* \param channel: pointer to channel data.
5242* \return DRXStatus_t.
5243*/
5244static int QAMSetSymbolrate(struct drxk_state *state)
5245{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005246 u32 adcFrequency = 0;
5247 u32 symbFreq = 0;
5248 u32 iqmRcRate = 0;
5249 u16 ratesel = 0;
5250 u32 lcSymbRate = 0;
5251 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005252
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005253 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005254 do {
5255 /* Select & calculate correct IQM rate */
5256 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5257 ratesel = 0;
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005258 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005259 if (state->param.u.qam.symbol_rate <= 1188750)
5260 ratesel = 3;
5261 else if (state->param.u.qam.symbol_rate <= 2377500)
5262 ratesel = 2;
5263 else if (state->param.u.qam.symbol_rate <= 4755000)
5264 ratesel = 1;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005265 status = Write16_0(state, IQM_FD_RATESEL__A, ratesel);
5266 if (status < 0)
5267 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005268
Oliver Endrissebc7de22011-07-03 13:49:44 -03005269 /*
5270 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5271 */
5272 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5273 if (symbFreq == 0) {
5274 /* Divide by zero */
5275 return -1;
5276 }
5277 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5278 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5279 (1 << 23);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005280 status = Write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate, 0);
5281 if (status < 0)
5282 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005283 state->m_iqmRcRate = iqmRcRate;
5284 /*
5285 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5286 */
5287 symbFreq = state->param.u.qam.symbol_rate;
5288 if (adcFrequency == 0) {
5289 /* Divide by zero */
5290 return -1;
5291 }
5292 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5293 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5294 16);
5295 if (lcSymbRate > 511)
5296 lcSymbRate = 511;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005297 status = Write16_0(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
5298 if (status < 0)
5299 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005300 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005301
Oliver Endrissebc7de22011-07-03 13:49:44 -03005302 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005303}
5304
5305/*============================================================================*/
5306
5307/**
5308* \brief Get QAM lock status.
5309* \param demod: instance of demod.
5310* \param channel: pointer to channel data.
5311* \return DRXStatus_t.
5312*/
5313
5314static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5315{
5316 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005317 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005318
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005319 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005320 status =
5321 scu_command(state,
5322 SCU_RAM_COMMAND_STANDARD_QAM |
5323 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5324 Result);
5325 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005326 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005327
5328 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005329 /* 0x0000 NOT LOCKED */
5330 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005331 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005332 /* 0x4000 DEMOD LOCKED */
5333 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005334 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005335 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5336 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005337 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005338 /* 0xC000 NEVER LOCKED */
5339 /* (system will never be able to lock to the signal) */
5340 /* TODO: check this, intermediate & standard specific lock states are not
5341 taken into account here */
5342 *pLockStatus = NEVER_LOCK;
5343 }
5344 return status;
5345}
5346
5347#define QAM_MIRROR__M 0x03
5348#define QAM_MIRROR_NORMAL 0x00
5349#define QAM_MIRRORED 0x01
5350#define QAM_MIRROR_AUTO_ON 0x02
5351#define QAM_LOCKRANGE__M 0x10
5352#define QAM_LOCKRANGE_NORMAL 0x10
5353
Oliver Endrissebc7de22011-07-03 13:49:44 -03005354static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5355 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005356{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005357 int status = 0;
5358 u8 parameterLen;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005359 u16 setEnvParameters[5];
5360 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5361 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005362
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005363 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005364 do {
5365 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005366 STEP 1: reset demodulator
5367 resets FEC DI and FEC RS
5368 resets QAM block
5369 resets SCU variables
5370 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005371 status = Write16_0(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
5372 if (status < 0)
5373 break;
5374 status = Write16_0(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5375 if (status < 0)
5376 break;
5377 status = QAMResetQAM(state);
5378 if (status < 0)
5379 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005380
5381 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03005382 STEP 2: configure demodulator
5383 -set env
5384 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5385 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005386 status = QAMSetSymbolrate(state);
5387 if (status < 0)
5388 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005389
5390 /* Env parameters */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005391 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005392 if (state->m_OperationMode == OM_QAM_ITU_C)
Oliver Endrissebc7de22011-07-03 13:49:44 -03005393 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005394 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005395 /* check for LOCKRANGE Extented */
5396 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005397 parameterLen = 4;
5398
5399 /* Set params */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005400 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005401 case QAM_256:
5402 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5403 break;
5404 case QAM_AUTO:
5405 case QAM_64:
5406 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5407 break;
5408 case QAM_16:
5409 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5410 break;
5411 case QAM_32:
5412 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5413 break;
5414 case QAM_128:
5415 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5416 break;
5417 default:
5418 status = -EINVAL;
5419 break;
5420 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005421 status = status;
5422 if (status < 0)
5423 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005424 setParamParameters[0] = state->m_Constellation; /* constellation */
5425 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005426
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005427 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5428 if (status < 0)
5429 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005430
5431
5432 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5433 setup constellation independent registers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005434#if 0
5435 status = SetFrequency (channel, tunerFreqOffset));
5436 if (status < 0)
5437 break;
5438#endif
5439 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5440 if (status < 0)
5441 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005442
5443 /* Setup BER measurement */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005444 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5445 if (status < 0)
5446 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005447
5448 /* Reset default values */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005449 status = Write16_0(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5450 if (status < 0)
5451 break;
5452 status = Write16_0(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5453 if (status < 0)
5454 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005455
Oliver Endrissebc7de22011-07-03 13:49:44 -03005456 /* Reset default LC values */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005457 status = Write16_0(state, QAM_LC_RATE_LIMIT__A, 3);
5458 if (status < 0)
5459 break;
5460 status = Write16_0(state, QAM_LC_LPF_FACTORP__A, 4);
5461 if (status < 0)
5462 break;
5463 status = Write16_0(state, QAM_LC_LPF_FACTORI__A, 4);
5464 if (status < 0)
5465 break;
5466 status = Write16_0(state, QAM_LC_MODE__A, 7);
5467 if (status < 0)
5468 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005469
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005470 status = Write16_0(state, QAM_LC_QUAL_TAB0__A, 1);
5471 if (status < 0)
5472 break;
5473 status = Write16_0(state, QAM_LC_QUAL_TAB1__A, 1);
5474 if (status < 0)
5475 break;
5476 status = Write16_0(state, QAM_LC_QUAL_TAB2__A, 1);
5477 if (status < 0)
5478 break;
5479 status = Write16_0(state, QAM_LC_QUAL_TAB3__A, 1);
5480 if (status < 0)
5481 break;
5482 status = Write16_0(state, QAM_LC_QUAL_TAB4__A, 2);
5483 if (status < 0)
5484 break;
5485 status = Write16_0(state, QAM_LC_QUAL_TAB5__A, 2);
5486 if (status < 0)
5487 break;
5488 status = Write16_0(state, QAM_LC_QUAL_TAB6__A, 2);
5489 if (status < 0)
5490 break;
5491 status = Write16_0(state, QAM_LC_QUAL_TAB8__A, 2);
5492 if (status < 0)
5493 break;
5494 status = Write16_0(state, QAM_LC_QUAL_TAB9__A, 2);
5495 if (status < 0)
5496 break;
5497 status = Write16_0(state, QAM_LC_QUAL_TAB10__A, 2);
5498 if (status < 0)
5499 break;
5500 status = Write16_0(state, QAM_LC_QUAL_TAB12__A, 2);
5501 if (status < 0)
5502 break;
5503 status = Write16_0(state, QAM_LC_QUAL_TAB15__A, 3);
5504 if (status < 0)
5505 break;
5506 status = Write16_0(state, QAM_LC_QUAL_TAB16__A, 3);
5507 if (status < 0)
5508 break;
5509 status = Write16_0(state, QAM_LC_QUAL_TAB20__A, 4);
5510 if (status < 0)
5511 break;
5512 status = Write16_0(state, QAM_LC_QUAL_TAB25__A, 4);
5513 if (status < 0)
5514 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005515
Oliver Endrissebc7de22011-07-03 13:49:44 -03005516 /* Mirroring, QAM-block starting point not inverted */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005517 status = Write16_0(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5518 if (status < 0)
5519 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005520
Oliver Endrissebc7de22011-07-03 13:49:44 -03005521 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005522 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5523 if (status < 0)
5524 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005525
Oliver Endrissebc7de22011-07-03 13:49:44 -03005526 /* STEP 4: constellation specific setup */
5527 switch (state->param.u.qam.modulation) {
5528 case QAM_16:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005529 status = SetQAM16(state);
5530 if (status < 0)
5531 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005532 break;
5533 case QAM_32:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005534 status = SetQAM32(state);
5535 if (status < 0)
5536 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005537 break;
5538 case QAM_AUTO:
5539 case QAM_64:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005540 status = SetQAM64(state);
5541 if (status < 0)
5542 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005543 break;
5544 case QAM_128:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005545 status = SetQAM128(state);
5546 if (status < 0)
5547 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005548 break;
5549 case QAM_256:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005550 status = SetQAM256(state);
5551 if (status < 0)
5552 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005553 break;
5554 default:
5555 return -1;
5556 break;
5557 } /* switch */
5558 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005559 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5560 if (status < 0)
5561 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005562
5563
Oliver Endrissebc7de22011-07-03 13:49:44 -03005564 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5565 /* extAttr->currentChannel.constellation = channel->constellation; */
5566 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005567 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5568 if (status < 0)
5569 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005570
Oliver Endrissebc7de22011-07-03 13:49:44 -03005571 /* Start processes */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005572 status = MPEGTSStart(state);
5573 if (status < 0)
5574 break;
5575 status = Write16_0(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5576 if (status < 0)
5577 break;
5578 status = Write16_0(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5579 if (status < 0)
5580 break;
5581 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5582 if (status < 0)
5583 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005584
Oliver Endrissebc7de22011-07-03 13:49:44 -03005585 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005586 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5587 if (status < 0)
5588 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005589
Oliver Endrissebc7de22011-07-03 13:49:44 -03005590 /* update global DRXK data container */
5591 /*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005592
Oliver Endrissebc7de22011-07-03 13:49:44 -03005593 /* All done, all OK */
5594 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005595
Oliver Endrissebc7de22011-07-03 13:49:44 -03005596 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005597 printk(KERN_ERR "drxk: %s %d\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005598
5599 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005600}
5601
Oliver Endrissebc7de22011-07-03 13:49:44 -03005602static int SetQAMStandard(struct drxk_state *state,
5603 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005604{
5605#ifdef DRXK_QAM_TAPS
5606#define DRXK_QAMA_TAPS_SELECT
5607#include "drxk_filters.h"
5608#undef DRXK_QAMA_TAPS_SELECT
5609#else
Oliver Endrissebc7de22011-07-03 13:49:44 -03005610 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005611#endif
5612
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005613 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005614 do {
5615 /* added antenna switch */
5616 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005617
Oliver Endrissebc7de22011-07-03 13:49:44 -03005618 /* Ensure correct power-up mode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005619 status = PowerUpQAM(state);
5620 if (status < 0)
5621 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005622 /* Reset QAM block */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005623 status = QAMResetQAM(state);
5624 if (status < 0)
5625 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005626
Oliver Endrissebc7de22011-07-03 13:49:44 -03005627 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005628
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005629 status = Write16_0(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5630 if (status < 0)
5631 break;
5632 status = Write16_0(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5633 if (status < 0)
5634 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005635
Oliver Endrissebc7de22011-07-03 13:49:44 -03005636 /* Upload IQM Channel Filter settings by
5637 boot loader from ROM table */
5638 switch (oMode) {
5639 case OM_QAM_ITU_A:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005640 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5641 if (status < 0)
5642 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005643 break;
5644 case OM_QAM_ITU_C:
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005645 status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5646 if (status < 0)
5647 break;
5648 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5649 if (status < 0)
5650 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005651 break;
5652 default:
5653 status = -EINVAL;
5654 }
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005655 status = status;
5656 if (status < 0)
5657 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005658
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005659 status = Write16_0(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5660 if (status < 0)
5661 break;
5662 status = Write16_0(state, IQM_CF_SYMMETRIC__A, 0);
5663 if (status < 0)
5664 break;
5665 status = Write16_0(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5666 if (status < 0)
5667 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005668
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005669 status = Write16_0(state, IQM_RC_STRETCH__A, 21);
5670 if (status < 0)
5671 break;
5672 status = Write16_0(state, IQM_AF_CLP_LEN__A, 0);
5673 if (status < 0)
5674 break;
5675 status = Write16_0(state, IQM_AF_CLP_TH__A, 448);
5676 if (status < 0)
5677 break;
5678 status = Write16_0(state, IQM_AF_SNS_LEN__A, 0);
5679 if (status < 0)
5680 break;
5681 status = Write16_0(state, IQM_CF_POW_MEAS_LEN__A, 0);
5682 if (status < 0)
5683 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005684
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005685 status = Write16_0(state, IQM_FS_ADJ_SEL__A, 1);
5686 if (status < 0)
5687 break;
5688 status = Write16_0(state, IQM_RC_ADJ_SEL__A, 1);
5689 if (status < 0)
5690 break;
5691 status = Write16_0(state, IQM_CF_ADJ_SEL__A, 1);
5692 if (status < 0)
5693 break;
5694 status = Write16_0(state, IQM_AF_UPD_SEL__A, 0);
5695 if (status < 0)
5696 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005697
Oliver Endrissebc7de22011-07-03 13:49:44 -03005698 /* IQM Impulse Noise Processing Unit */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005699 status = Write16_0(state, IQM_CF_CLP_VAL__A, 500);
5700 if (status < 0)
5701 break;
5702 status = Write16_0(state, IQM_CF_DATATH__A, 1000);
5703 if (status < 0)
5704 break;
5705 status = Write16_0(state, IQM_CF_BYPASSDET__A, 1);
5706 if (status < 0)
5707 break;
5708 status = Write16_0(state, IQM_CF_DET_LCT__A, 0);
5709 if (status < 0)
5710 break;
5711 status = Write16_0(state, IQM_CF_WND_LEN__A, 1);
5712 if (status < 0)
5713 break;
5714 status = Write16_0(state, IQM_CF_PKDTH__A, 1);
5715 if (status < 0)
5716 break;
5717 status = Write16_0(state, IQM_AF_INC_BYPASS__A, 1);
5718 if (status < 0)
5719 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005720
Oliver Endrissebc7de22011-07-03 13:49:44 -03005721 /* turn on IQMAF. Must be done before setAgc**() */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005722 status = SetIqmAf(state, true);
5723 if (status < 0)
5724 break;
5725 status = Write16_0(state, IQM_AF_START_LOCK__A, 0x01);
5726 if (status < 0)
5727 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005728
Oliver Endrissebc7de22011-07-03 13:49:44 -03005729 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005730 status = ADCSynchronization(state);
5731 if (status < 0)
5732 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005733
Oliver Endrissebc7de22011-07-03 13:49:44 -03005734 /* Set the FSM step period */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005735 status = Write16_0(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5736 if (status < 0)
5737 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005738
Oliver Endrissebc7de22011-07-03 13:49:44 -03005739 /* Halt SCU to enable safe non-atomic accesses */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005740 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5741 if (status < 0)
5742 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005743
Oliver Endrissebc7de22011-07-03 13:49:44 -03005744 /* No more resets of the IQM, current standard correctly set =>
5745 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005746
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005747 status = InitAGC(state, true);
5748 if (status < 0)
5749 break;
5750 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5751 if (status < 0)
5752 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005753
Oliver Endrissebc7de22011-07-03 13:49:44 -03005754 /* Configure AGC's */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005755 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5756 if (status < 0)
5757 break;
5758 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5759 if (status < 0)
5760 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005761
Oliver Endrissebc7de22011-07-03 13:49:44 -03005762 /* Activate SCU to enable SCU commands */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005763 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5764 if (status < 0)
5765 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005766 } while (0);
5767 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005768}
5769
5770static int WriteGPIO(struct drxk_state *state)
5771{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005772 int status;
5773 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005774
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005775 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005776 do {
5777 /* stop lock indicator process */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005778 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5779 if (status < 0)
5780 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005781
Oliver Endrissebc7de22011-07-03 13:49:44 -03005782 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005783 status = Write16_0(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5784 if (status < 0)
5785 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005786
Oliver Endrissebc7de22011-07-03 13:49:44 -03005787 if (state->m_hasSAWSW) {
5788 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005789 status = Write16_0(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5790 if (status < 0)
5791 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005792
Oliver Endrissebc7de22011-07-03 13:49:44 -03005793 /* use corresponding bit in io data output registar */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005794 status = Read16_0(state, SIO_PDR_UIO_OUT_LO__A, &value);
5795 if (status < 0)
5796 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005797 if (state->m_GPIO == 0)
5798 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5799 else
5800 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5801 /* write back to io data output register */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005802 status = Write16_0(state, SIO_PDR_UIO_OUT_LO__A, value);
5803 if (status < 0)
5804 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005805
Oliver Endrissebc7de22011-07-03 13:49:44 -03005806 }
5807 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005808 status = Write16_0(state, SIO_TOP_COMM_KEY__A, 0x0000);
5809 if (status < 0)
5810 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005811 } while (0);
5812 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005813}
5814
5815static int SwitchAntennaToQAM(struct drxk_state *state)
5816{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005817 int status = -1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005818
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005819 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005820 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5821 if (state->m_GPIO != state->m_AntennaDVBC) {
5822 state->m_GPIO = state->m_AntennaDVBC;
5823 status = WriteGPIO(state);
5824 }
5825 }
5826 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005827}
5828
5829static int SwitchAntennaToDVBT(struct drxk_state *state)
5830{
5831 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005832
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005833 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005834 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5835 if (state->m_GPIO != state->m_AntennaDVBT) {
5836 state->m_GPIO = state->m_AntennaDVBT;
5837 status = WriteGPIO(state);
5838 }
5839 }
5840 return status;
5841}
5842
5843
5844static int PowerDownDevice(struct drxk_state *state)
5845{
5846 /* Power down to requested mode */
5847 /* Backup some register settings */
5848 /* Set pins with possible pull-ups connected to them in input mode */
5849 /* Analog power down */
5850 /* ADC power down */
5851 /* Power down device */
5852 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005853
5854 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005855 do {
5856 if (state->m_bPDownOpenBridge) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03005857 /* Open I2C bridge before power down of DRXK */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005858 status = ConfigureI2CBridge(state, true);
5859 if (status < 0)
5860 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005861 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005862 /* driver 0.9.0 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005863 status = DVBTEnableOFDMTokenRing(state, false);
5864 if (status < 0)
5865 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005866
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005867 status = Write16_0(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5868 if (status < 0)
5869 break;
5870 status = Write16_0(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5871 if (status < 0)
5872 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005873 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005874 status = HI_CfgCommand(state);
5875 if (status < 0)
5876 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005877 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005878
Oliver Endrissebc7de22011-07-03 13:49:44 -03005879 if (status < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005880 return -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005881
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005882 return 0;
5883}
5884
5885static int load_microcode(struct drxk_state *state, char *mc_name)
5886{
5887 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005888 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005889
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005890 dprintk(1, "\n");
5891
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005892 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5893 if (err < 0) {
5894 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005895 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005896 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005897 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005898 return err;
5899 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005900 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005901 release_firmware(fw);
5902 return err;
5903}
5904
5905static int init_drxk(struct drxk_state *state)
5906{
5907 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005908 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005909 u16 driverVersion;
5910
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005911 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005912 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
5913 do {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005914 status = PowerUpDevice(state);
5915 if (status < 0)
5916 break;
5917 status = DRXX_Open(state);
5918 if (status < 0)
5919 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005920 /* Soft reset of OFDM-, sys- and osc-clockdomain */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005921 status = Write16_0(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
5922 if (status < 0)
5923 break;
5924 status = Write16_0(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5925 if (status < 0)
5926 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005927 /* TODO is this needed, if yes how much delay in worst case scenario */
5928 msleep(1);
5929 state->m_DRXK_A3_PATCH_CODE = true;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005930 status = GetDeviceCapabilities(state);
5931 if (status < 0)
5932 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005933
5934 /* Bridge delay, uses oscilator clock */
5935 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5936 /* SDA brdige delay */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005937 state->m_HICfgBridgeDelay =
5938 (u16) ((state->m_oscClockFreq / 1000) *
5939 HI_I2C_BRIDGE_DELAY) / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005940 /* Clipping */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005941 if (state->m_HICfgBridgeDelay >
5942 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
5943 state->m_HICfgBridgeDelay =
5944 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005945 }
5946 /* SCL bridge delay, same as SDA for now */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005947 state->m_HICfgBridgeDelay +=
5948 state->m_HICfgBridgeDelay <<
5949 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005950
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005951 status = InitHI(state);
5952 if (status < 0)
5953 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005954 /* disable various processes */
5955#if NOA1ROM
Oliver Endrissebc7de22011-07-03 13:49:44 -03005956 if (!(state->m_DRXK_A1_ROM_CODE)
5957 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005958#endif
5959 {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005960 status = Write16_0(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5961 if (status < 0)
5962 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005963 }
5964
5965 /* disable MPEG port */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005966 status = MPEGTSDisable(state);
5967 if (status < 0)
5968 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005969
5970 /* Stop AUD and SCU */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005971 status = Write16_0(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
5972 if (status < 0)
5973 break;
5974 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
5975 if (status < 0)
5976 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005977
5978 /* enable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005979 status = Write16_0(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
5980 if (status < 0)
5981 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005982
5983 /* include boot loader section */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005984 status = Write16_0(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
5985 if (status < 0)
5986 break;
5987 status = BLChainCmd(state, 0, 6, 100);
5988 if (status < 0)
5989 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005990
5991#if 0
5992 if (state->m_DRXK_A3_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005993 status = DownloadMicrocode(state, DRXK_A3_microcode, DRXK_A3_microcode_length);
5994 if (status < 0)
5995 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005996#else
5997 load_microcode(state, "drxk_a3.mc");
5998#endif
5999#if NOA1ROM
6000 if (state->m_DRXK_A2_PATCH_CODE)
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006001 status = DownloadMicrocode(state, DRXK_A2_microcode, DRXK_A2_microcode_length);
6002 if (status < 0)
6003 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006004#endif
6005 /* disable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006006 status = Write16_0(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6007 if (status < 0)
6008 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006009
6010 /* Run SCU for a little while to initialize microcode version numbers */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006011 status = Write16_0(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6012 if (status < 0)
6013 break;
6014 status = DRXX_Open(state);
6015 if (status < 0)
6016 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006017 /* added for test */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006018 msleep(30);
6019
6020 powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006021 status = CtrlPowerMode(state, &powerMode);
6022 if (status < 0)
6023 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006024
6025 /* Stamp driver version number in SCU data RAM in BCD code
6026 Done to enable field application engineers to retreive drxdriver version
6027 via I2C from SCU RAM.
6028 Not using SCU command interface for SCU register access since no
6029 microcode may be present.
Oliver Endrissebc7de22011-07-03 13:49:44 -03006030 */
6031 driverVersion =
6032 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6033 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6034 ((DRXK_VERSION_MAJOR % 10) << 4) +
6035 (DRXK_VERSION_MINOR % 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006036 status = Write16_0(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6037 if (status < 0)
6038 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006039 driverVersion =
6040 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6041 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6042 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6043 (DRXK_VERSION_PATCH % 10);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006044 status = Write16_0(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6045 if (status < 0)
6046 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006047
Oliver Endrissebc7de22011-07-03 13:49:44 -03006048 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6049 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6050 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006051
6052 /* Dirty fix of default values for ROM/PATCH microcode
6053 Dirty because this fix makes it impossible to setup suitable values
6054 before calling DRX_Open. This solution requires changes to RF AGC speed
6055 to be done via the CTRL function after calling DRX_Open */
6056
Oliver Endrissebc7de22011-07-03 13:49:44 -03006057 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006058
6059 /* Reset driver debug flags to 0 */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006060 status = Write16_0(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6061 if (status < 0)
6062 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006063 /* driver 0.9.0 */
6064 /* Setup FEC OC:
6065 NOTE: No more full FEC resets allowed afterwards!! */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006066 status = Write16_0(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6067 if (status < 0)
6068 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006069 /* MPEGTS functions are still the same */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006070 status = MPEGTSDtoInit(state);
6071 if (status < 0)
6072 break;
6073 status = MPEGTSStop(state);
6074 if (status < 0)
6075 break;
6076 status = MPEGTSConfigurePolarity(state);
6077 if (status < 0)
6078 break;
6079 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6080 if (status < 0)
6081 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006082 /* added: configure GPIO */
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006083 status = WriteGPIO(state);
6084 if (status < 0)
6085 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006086
Oliver Endrissebc7de22011-07-03 13:49:44 -03006087 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006088
6089 if (state->m_bPowerDown) {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006090 status = PowerDownDevice(state);
6091 if (status < 0)
6092 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006093 state->m_DrxkState = DRXK_POWERED_DOWN;
6094 } else
6095 state->m_DrxkState = DRXK_STOPPED;
6096 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006097 }
6098
6099 return 0;
6100}
6101
Oliver Endrissebc7de22011-07-03 13:49:44 -03006102static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006103{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006104 struct drxk_state *state = fe->demodulator_priv;
6105
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006106 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006107 kfree(state);
6108}
6109
Oliver Endrissebc7de22011-07-03 13:49:44 -03006110static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006111{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006112 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006113
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006114 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006115 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006116 return -EBUSY;
6117 SetOperationMode(state, OM_QAM_ITU_A);
6118 return 0;
6119}
6120
Oliver Endrissebc7de22011-07-03 13:49:44 -03006121static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006122{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006123 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006124
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006125 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006126 ShutDown(state);
6127 mutex_unlock(&state->ctlock);
6128 return 0;
6129}
6130
Oliver Endrissebc7de22011-07-03 13:49:44 -03006131static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006132{
6133 struct drxk_state *state = fe->demodulator_priv;
6134
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006135 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006136 return ConfigureI2CBridge(state, enable ? true : false);
6137}
6138
Oliver Endrissebc7de22011-07-03 13:49:44 -03006139static int drxk_set_parameters(struct dvb_frontend *fe,
6140 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006141{
6142 struct drxk_state *state = fe->demodulator_priv;
6143 u32 IF;
6144
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006145 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006146 if (fe->ops.i2c_gate_ctrl)
6147 fe->ops.i2c_gate_ctrl(fe, 1);
6148 if (fe->ops.tuner_ops.set_params)
6149 fe->ops.tuner_ops.set_params(fe, p);
6150 if (fe->ops.i2c_gate_ctrl)
6151 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006152 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006153 fe->ops.tuner_ops.get_frequency(fe, &IF);
6154 Start(state, 0, IF);
6155
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006156 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006157
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006158 return 0;
6159}
6160
Oliver Endrissebc7de22011-07-03 13:49:44 -03006161static int drxk_c_get_frontend(struct dvb_frontend *fe,
6162 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006163{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006164 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006165 return 0;
6166}
6167
6168static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6169{
6170 struct drxk_state *state = fe->demodulator_priv;
6171 u32 stat;
6172
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006173 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006174 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006175 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006176 if (stat == MPEG_LOCK)
6177 *status |= 0x1f;
6178 if (stat == FEC_LOCK)
6179 *status |= 0x0f;
6180 if (stat == DEMOD_LOCK)
6181 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006182 return 0;
6183}
6184
6185static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6186{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006187 dprintk(1, "\n");
6188
Oliver Endrissebc7de22011-07-03 13:49:44 -03006189 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006190 return 0;
6191}
6192
Oliver Endrissebc7de22011-07-03 13:49:44 -03006193static int drxk_read_signal_strength(struct dvb_frontend *fe,
6194 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006195{
6196 struct drxk_state *state = fe->demodulator_priv;
6197 u32 val;
6198
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006199 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006200 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006201 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006202 return 0;
6203}
6204
6205static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6206{
6207 struct drxk_state *state = fe->demodulator_priv;
6208 s32 snr2;
6209
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006210 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006211 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006212 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006213 return 0;
6214}
6215
6216static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6217{
6218 struct drxk_state *state = fe->demodulator_priv;
6219 u16 err;
6220
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006221 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006222 DVBTQAMGetAccPktErr(state, &err);
6223 *ucblocks = (u32) err;
6224 return 0;
6225}
6226
Oliver Endrissebc7de22011-07-03 13:49:44 -03006227static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6228 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006229{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006230 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006231 sets->min_delay_ms = 3000;
6232 sets->max_drift = 0;
6233 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006234 return 0;
6235}
6236
Oliver Endrissebc7de22011-07-03 13:49:44 -03006237static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006238{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006239#if 0
6240 struct drxk_state *state = fe->demodulator_priv;
6241
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006242 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006243 kfree(state);
6244#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006245}
6246
Oliver Endrissebc7de22011-07-03 13:49:44 -03006247static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006248{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006249 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006250
6251 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006252 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006253 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006254 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006255 return 0;
6256}
6257
Oliver Endrissebc7de22011-07-03 13:49:44 -03006258static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006259{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006260 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006261
6262 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006263 mutex_unlock(&state->ctlock);
6264 return 0;
6265}
6266
Oliver Endrissebc7de22011-07-03 13:49:44 -03006267static int drxk_t_get_frontend(struct dvb_frontend *fe,
6268 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006269{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006270 dprintk(1, "\n");
6271
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006272 return 0;
6273}
6274
6275static struct dvb_frontend_ops drxk_c_ops = {
6276 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006277 .name = "DRXK DVB-C",
6278 .type = FE_QAM,
6279 .frequency_stepsize = 62500,
6280 .frequency_min = 47000000,
6281 .frequency_max = 862000000,
6282 .symbol_rate_min = 870000,
6283 .symbol_rate_max = 11700000,
6284 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6285 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006286 .release = drxk_c_release,
6287 .init = drxk_c_init,
6288 .sleep = drxk_c_sleep,
6289 .i2c_gate_ctrl = drxk_gate_ctrl,
6290
6291 .set_frontend = drxk_set_parameters,
6292 .get_frontend = drxk_c_get_frontend,
6293 .get_tune_settings = drxk_c_get_tune_settings,
6294
6295 .read_status = drxk_read_status,
6296 .read_ber = drxk_read_ber,
6297 .read_signal_strength = drxk_read_signal_strength,
6298 .read_snr = drxk_read_snr,
6299 .read_ucblocks = drxk_read_ucblocks,
6300};
6301
6302static struct dvb_frontend_ops drxk_t_ops = {
6303 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006304 .name = "DRXK DVB-T",
6305 .type = FE_OFDM,
6306 .frequency_min = 47125000,
6307 .frequency_max = 865000000,
6308 .frequency_stepsize = 166667,
6309 .frequency_tolerance = 0,
6310 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6311 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6312 FE_CAN_FEC_AUTO |
6313 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6314 FE_CAN_QAM_AUTO |
6315 FE_CAN_TRANSMISSION_MODE_AUTO |
6316 FE_CAN_GUARD_INTERVAL_AUTO |
6317 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006318 .release = drxk_t_release,
6319 .init = drxk_t_init,
6320 .sleep = drxk_t_sleep,
6321 .i2c_gate_ctrl = drxk_gate_ctrl,
6322
6323 .set_frontend = drxk_set_parameters,
6324 .get_frontend = drxk_t_get_frontend,
6325
6326 .read_status = drxk_read_status,
6327 .read_ber = drxk_read_ber,
6328 .read_signal_strength = drxk_read_signal_strength,
6329 .read_snr = drxk_read_snr,
6330 .read_ucblocks = drxk_read_ucblocks,
6331};
6332
6333struct dvb_frontend *drxk_attach(struct i2c_adapter *i2c, u8 adr,
6334 struct dvb_frontend **fe_t)
6335{
6336 struct drxk_state *state = NULL;
6337
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006338 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006339 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006340 if (!state)
6341 return NULL;
6342
Oliver Endrissebc7de22011-07-03 13:49:44 -03006343 state->i2c = i2c;
6344 state->demod_address = adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006345
6346 mutex_init(&state->mutex);
6347 mutex_init(&state->ctlock);
6348
Oliver Endrissebc7de22011-07-03 13:49:44 -03006349 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6350 sizeof(struct dvb_frontend_ops));
6351 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6352 sizeof(struct dvb_frontend_ops));
6353 state->c_frontend.demodulator_priv = state;
6354 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006355
6356 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006357 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006358 goto error;
6359 *fe_t = &state->t_frontend;
6360 return &state->c_frontend;
6361
6362error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006363 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006364 kfree(state);
6365 return NULL;
6366}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006367EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006368
6369MODULE_DESCRIPTION("DRX-K driver");
6370MODULE_AUTHOR("Ralph Metzler");
6371MODULE_LICENSE("GPL");