blob: 1d29ed23154fc6314bafea77f72a24208dbb7ee2 [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 };
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300321
322 return i2c_transfer(adapter, msgs, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300323}
324
325static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
326{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300327 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300328 struct i2c_msg msg = {
329 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300330
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300331 dprintk(3, ":");
332 if (debug > 2) {
333 int i;
334 for (i = 0; i < len; i++)
335 printk(KERN_CONT " %02x", data[i]);
336 printk(KERN_CONT "\n");
337 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300338 status = i2c_transfer(adap, &msg, 1);
339 if (status >= 0 && status != 1)
340 status = -EIO;
341
342 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300343 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300344
345 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300346}
347
348static int i2c_read(struct i2c_adapter *adap,
349 u8 adr, u8 *msg, int len, u8 *answ, int alen)
350{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300351 int status;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300352 struct i2c_msg msgs[2] = {
353 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300354 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300355 {.addr = adr, .flags = I2C_M_RD,
356 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300357 };
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300358 dprintk(3, ":");
359 if (debug > 2) {
360 int i;
361 for (i = 0; i < len; i++)
362 printk(KERN_CONT " %02x", msg[i]);
363 printk(KERN_CONT "\n");
364 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300365 status = i2c_transfer(adap, msgs, 2);
366 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300367 if (debug > 2)
368 printk(KERN_CONT ": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300369 if (status >= 0)
370 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300371
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300372 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300373 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300374 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300375 if (debug > 2) {
376 int i;
377 printk(KERN_CONT ": Read ");
378 for (i = 0; i < len; i++)
379 printk(KERN_CONT " %02x", msg[i]);
380 printk(KERN_CONT "\n");
381 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300382 return 0;
383}
384
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300385static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300386{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300387 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300388 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300389
390 if (state->single_master)
391 flags |= 0xC0;
392
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300393 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
394 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
395 mm1[1] = ((reg >> 16) & 0xFF);
396 mm1[2] = ((reg >> 24) & 0xFF) | flags;
397 mm1[3] = ((reg >> 7) & 0xFF);
398 len = 4;
399 } else {
400 mm1[0] = ((reg << 1) & 0xFF);
401 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
402 len = 2;
403 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300404 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300405 status = i2c_read(state->i2c, adr, mm1, len, mm2, 2);
406 if (status < 0)
407 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300408 if (data)
409 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300410
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300411 return 0;
412}
413
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300414static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300415{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300416 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300417}
418
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300419static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300420{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300421 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300422 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300423
424 if (state->single_master)
425 flags |= 0xC0;
426
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300427 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
428 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
429 mm1[1] = ((reg >> 16) & 0xFF);
430 mm1[2] = ((reg >> 24) & 0xFF) | flags;
431 mm1[3] = ((reg >> 7) & 0xFF);
432 len = 4;
433 } else {
434 mm1[0] = ((reg << 1) & 0xFF);
435 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
436 len = 2;
437 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300438 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300439 status = i2c_read(state->i2c, adr, mm1, len, mm2, 4);
440 if (status < 0)
441 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300442 if (data)
443 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300444 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300445
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300446 return 0;
447}
448
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300449static int read32(struct drxk_state *state, u32 reg, u32 *data)
450{
451 return read32_flags(state, reg, data, 0);
452}
453
454static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300455{
456 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300457
458 if (state->single_master)
459 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300460 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
461 mm[0] = (((reg << 1) & 0xFF) | 0x01);
462 mm[1] = ((reg >> 16) & 0xFF);
463 mm[2] = ((reg >> 24) & 0xFF) | flags;
464 mm[3] = ((reg >> 7) & 0xFF);
465 len = 4;
466 } else {
467 mm[0] = ((reg << 1) & 0xFF);
468 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
469 len = 2;
470 }
471 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300472 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300473
474 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300475 return i2c_write(state->i2c, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300476}
477
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300478static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300479{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300480 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300481}
482
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300483static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300484{
485 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300486
487 if (state->single_master)
488 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300489 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
490 mm[0] = (((reg << 1) & 0xFF) | 0x01);
491 mm[1] = ((reg >> 16) & 0xFF);
492 mm[2] = ((reg >> 24) & 0xFF) | flags;
493 mm[3] = ((reg >> 7) & 0xFF);
494 len = 4;
495 } else {
496 mm[0] = ((reg << 1) & 0xFF);
497 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
498 len = 2;
499 }
500 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300501 mm[len + 1] = (data >> 8) & 0xff;
502 mm[len + 2] = (data >> 16) & 0xff;
503 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300504 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300505
506 return i2c_write(state->i2c, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300507}
508
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300509static int write32(struct drxk_state *state, u32 reg, u32 data)
510{
511 return write32_flags(state, reg, data, 0);
512}
513
514static int write_block(struct drxk_state *state, u32 Address,
515 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300516{
517 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300518 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300519
520 if (state->single_master)
521 Flags |= 0xC0;
522
Oliver Endrissebc7de22011-07-03 13:49:44 -0300523 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300524 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300525 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300526 u8 *AdrBuf = &state->Chunk[0];
527 u32 AdrLength = 0;
528
Oliver Endrissebc7de22011-07-03 13:49:44 -0300529 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
530 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
531 AdrBuf[1] = ((Address >> 16) & 0xFF);
532 AdrBuf[2] = ((Address >> 24) & 0xFF);
533 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300534 AdrBuf[2] |= Flags;
535 AdrLength = 4;
536 if (Chunk == state->m_ChunkSize)
537 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300538 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300539 AdrBuf[0] = ((Address << 1) & 0xFF);
540 AdrBuf[1] = (((Address >> 16) & 0x0F) |
541 ((Address >> 18) & 0xF0));
542 AdrLength = 2;
543 }
544 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300545 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
546 if (debug > 1) {
547 int i;
548 if (pBlock)
549 for (i = 0; i < Chunk; i++)
550 printk(KERN_CONT " %02x", pBlock[i]);
551 printk(KERN_CONT "\n");
552 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300553 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300554 &state->Chunk[0], Chunk + AdrLength);
555 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300556 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
557 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300558 break;
559 }
560 pBlock += Chunk;
561 Address += (Chunk >> 1);
562 BlkSize -= Chunk;
563 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300564 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300565}
566
567#ifndef DRXK_MAX_RETRIES_POWERUP
568#define DRXK_MAX_RETRIES_POWERUP 20
569#endif
570
571int PowerUpDevice(struct drxk_state *state)
572{
573 int status;
574 u8 data = 0;
575 u16 retryCount = 0;
576
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300577 dprintk(1, "\n");
578
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300579 status = i2c_read1(state->i2c, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300580 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300581 do {
582 data = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300583 status = i2c_write(state->i2c, state->demod_address,
584 &data, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300585 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300586 retryCount++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300587 if (status < 0)
588 continue;
589 status = i2c_read1(state->i2c, state->demod_address,
590 &data);
591 } while (status < 0 &&
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300592 (retryCount < DRXK_MAX_RETRIES_POWERUP));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300593 if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
594 goto error;
595 }
596
597 /* Make sure all clk domains are active */
598 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
599 if (status < 0)
600 goto error;
601 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
602 if (status < 0)
603 goto error;
604 /* Enable pll lock tests */
605 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
606 if (status < 0)
607 goto error;
608
609 state->m_currentPowerMode = DRX_POWER_UP;
610
611error:
612 if (status < 0)
613 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
614
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300615 return status;
616}
617
618
619static int init_state(struct drxk_state *state)
620{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300621 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
622 u32 ulVSBIfAgcOutputLevel = 0;
623 u32 ulVSBIfAgcMinLevel = 0;
624 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
625 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300626
Oliver Endrissebc7de22011-07-03 13:49:44 -0300627 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
628 u32 ulVSBRfAgcOutputLevel = 0;
629 u32 ulVSBRfAgcMinLevel = 0;
630 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
631 u32 ulVSBRfAgcSpeed = 3;
632 u32 ulVSBRfAgcTop = 9500;
633 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300634
Oliver Endrissebc7de22011-07-03 13:49:44 -0300635 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
636 u32 ulATVIfAgcOutputLevel = 0;
637 u32 ulATVIfAgcMinLevel = 0;
638 u32 ulATVIfAgcMaxLevel = 0;
639 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300640
Oliver Endrissebc7de22011-07-03 13:49:44 -0300641 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
642 u32 ulATVRfAgcOutputLevel = 0;
643 u32 ulATVRfAgcMinLevel = 0;
644 u32 ulATVRfAgcMaxLevel = 0;
645 u32 ulATVRfAgcTop = 9500;
646 u32 ulATVRfAgcCutOffCurrent = 4000;
647 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300648
649 u32 ulQual83 = DEFAULT_MER_83;
650 u32 ulQual93 = DEFAULT_MER_93;
651
652 u32 ulDVBTStaticTSClock = 1;
653 u32 ulDVBCStaticTSClock = 1;
654
655 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
656 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
657
658 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
659 /* io_pad_cfg_mode output mode is drive always */
660 /* io_pad_cfg_drive is set to power 2 (23 mA) */
661 u32 ulGPIOCfg = 0x0113;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300662 u32 ulGPIO = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300663 u32 ulSerialMode = 1;
664 u32 ulInvertTSClock = 0;
665 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
666 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
667 u32 ulDVBTBitrate = 50000000;
668 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
669
670 u32 ulInsertRSByte = 0;
671
672 u32 ulRfMirror = 1;
673 u32 ulPowerDown = 0;
674
675 u32 ulAntennaDVBT = 1;
676 u32 ulAntennaDVBC = 0;
677 u32 ulAntennaSwitchDVBTDVBC = 0;
678
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300679 dprintk(1, "\n");
680
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300681 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300682 state->m_hasDVBT = false;
683 state->m_hasDVBC = false;
684 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300685 state->m_hasOOB = false;
686 state->m_hasAudio = false;
687
688 state->m_ChunkSize = 124;
689
690 state->m_oscClockFreq = 0;
691 state->m_smartAntInverted = false;
692 state->m_bPDownOpenBridge = false;
693
694 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300695 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300696 /* Timing div, 250ns/Psys */
697 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
698 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
699 HI_I2C_DELAY) / 1000;
700 /* Clipping */
701 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
702 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
703 state->m_HICfgWakeUpKey = (state->demod_address << 1);
704 /* port/bridge/power down ctrl */
705 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
706
707 state->m_bPowerDown = (ulPowerDown != 0);
708
709 state->m_DRXK_A1_PATCH_CODE = false;
710 state->m_DRXK_A1_ROM_CODE = false;
711 state->m_DRXK_A2_ROM_CODE = false;
712 state->m_DRXK_A3_ROM_CODE = false;
713 state->m_DRXK_A2_PATCH_CODE = false;
714 state->m_DRXK_A3_PATCH_CODE = false;
715
716 /* Init AGC and PGA parameters */
717 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300718 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
719 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
720 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
721 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
722 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300723 state->m_vsbPgaCfg = 140;
724
725 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300726 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
727 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
728 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
729 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
730 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
731 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
732 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
733 state->m_vsbPreSawCfg.reference = 0x07;
734 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300735
736 state->m_Quality83percent = DEFAULT_MER_83;
737 state->m_Quality93percent = DEFAULT_MER_93;
738 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
739 state->m_Quality83percent = ulQual83;
740 state->m_Quality93percent = ulQual93;
741 }
742
743 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300744 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
745 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
746 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
747 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
748 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300749
750 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300751 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
752 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
753 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
754 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
755 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
756 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
757 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
758 state->m_atvPreSawCfg.reference = 0x04;
759 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300760
761
762 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300763 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
764 state->m_dvbtRfAgcCfg.outputLevel = 0;
765 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
766 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
767 state->m_dvbtRfAgcCfg.top = 0x2100;
768 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
769 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300770
771
772 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300773 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
774 state->m_dvbtIfAgcCfg.outputLevel = 0;
775 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
776 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
777 state->m_dvbtIfAgcCfg.top = 13424;
778 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
779 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300780 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300781 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
782 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300783
Oliver Endrissebc7de22011-07-03 13:49:44 -0300784 state->m_dvbtPreSawCfg.reference = 4;
785 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300786
787 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300788 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
789 state->m_qamRfAgcCfg.outputLevel = 0;
790 state->m_qamRfAgcCfg.minOutputLevel = 6023;
791 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
792 state->m_qamRfAgcCfg.top = 0x2380;
793 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
794 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300795
796 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300797 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
798 state->m_qamIfAgcCfg.outputLevel = 0;
799 state->m_qamIfAgcCfg.minOutputLevel = 0;
800 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
801 state->m_qamIfAgcCfg.top = 0x0511;
802 state->m_qamIfAgcCfg.cutOffCurrent = 0;
803 state->m_qamIfAgcCfg.speed = 3;
804 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300805 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
806
Oliver Endrissebc7de22011-07-03 13:49:44 -0300807 state->m_qamPgaCfg = 140;
808 state->m_qamPreSawCfg.reference = 4;
809 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300810
811 state->m_OperationMode = OM_NONE;
812 state->m_DrxkState = DRXK_UNINITIALIZED;
813
814 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300815 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
816 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
817 state->m_enableParallel = true; /* If TRUE;
818 parallel out otherwise serial */
819 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
820 state->m_invertERR = false; /* If TRUE; invert ERR signal */
821 state->m_invertSTR = false; /* If TRUE; invert STR signals */
822 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
823 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300824 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300825 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300826 /* If TRUE; static MPEG clockrate will be used;
827 otherwise clockrate will adapt to the bitrate of the TS */
828
829 state->m_DVBTBitrate = ulDVBTBitrate;
830 state->m_DVBCBitrate = ulDVBCBitrate;
831
832 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
833 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
834
835 /* Maximum bitrate in b/s in case static clockrate is selected */
836 state->m_mpegTsStaticBitrate = 19392658;
837 state->m_disableTEIhandling = false;
838
839 if (ulInsertRSByte)
840 state->m_insertRSByte = true;
841
842 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
843 if (ulMpegLockTimeOut < 10000)
844 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
845 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
846 if (ulDemodLockTimeOut < 10000)
847 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
848
Oliver Endrissebc7de22011-07-03 13:49:44 -0300849 /* QAM defaults */
850 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300851 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300852 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
853 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300854
855 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
856 state->m_agcFastClipCtrlDelay = 0;
857
858 state->m_GPIOCfg = (ulGPIOCfg);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300859 state->m_GPIO = (ulGPIO == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300860
861 state->m_AntennaDVBT = (ulAntennaDVBT == 0 ? 0 : 1);
862 state->m_AntennaDVBC = (ulAntennaDVBC == 0 ? 0 : 1);
863 state->m_AntennaSwitchDVBTDVBC =
Oliver Endrissebc7de22011-07-03 13:49:44 -0300864 (ulAntennaSwitchDVBTDVBC == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300865
866 state->m_bPowerDown = false;
867 state->m_currentPowerMode = DRX_POWER_DOWN;
868
869 state->m_enableParallel = (ulSerialMode == 0);
870
871 state->m_rfmirror = (ulRfMirror == 0);
872 state->m_IfAgcPol = false;
873 return 0;
874}
875
876static int DRXX_Open(struct drxk_state *state)
877{
878 int status = 0;
879 u32 jtag = 0;
880 u16 bid = 0;
881 u16 key = 0;
882
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300883 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300884 /* stop lock indicator process */
885 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
886 if (status < 0)
887 goto error;
888 /* Check device id */
889 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
890 if (status < 0)
891 goto error;
892 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
893 if (status < 0)
894 goto error;
895 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
896 if (status < 0)
897 goto error;
898 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
899 if (status < 0)
900 goto error;
901 status = write16(state, SIO_TOP_COMM_KEY__A, key);
902error:
903 if (status < 0)
904 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300905 return status;
906}
907
908static int GetDeviceCapabilities(struct drxk_state *state)
909{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300910 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300911 u32 sioTopJtagidLo = 0;
912 int status;
913
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300914 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300915
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300916 /* driver 0.9.0 */
917 /* stop lock indicator process */
918 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
919 if (status < 0)
920 goto error;
921 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
922 if (status < 0)
923 goto error;
924 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
925 if (status < 0)
926 goto error;
927 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
928 if (status < 0)
929 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300930
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300931 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
932 case 0:
933 /* ignore (bypass ?) */
934 break;
935 case 1:
936 /* 27 MHz */
937 state->m_oscClockFreq = 27000;
938 break;
939 case 2:
940 /* 20.25 MHz */
941 state->m_oscClockFreq = 20250;
942 break;
943 case 3:
944 /* 4 MHz */
945 state->m_oscClockFreq = 20250;
946 break;
947 default:
948 printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
949 return -EINVAL;
950 }
951 /*
952 Determine device capabilities
953 Based on pinning v14
954 */
955 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
956 if (status < 0)
957 goto error;
958 /* driver 0.9.0 */
959 switch ((sioTopJtagidLo >> 29) & 0xF) {
960 case 0:
961 state->m_deviceSpin = DRXK_SPIN_A1;
962 break;
963 case 2:
964 state->m_deviceSpin = DRXK_SPIN_A2;
965 break;
966 case 3:
967 state->m_deviceSpin = DRXK_SPIN_A3;
968 break;
969 default:
970 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
971 status = -EINVAL;
972 printk(KERN_ERR "drxk: Spin unknown\n");
973 goto error2;
974 }
975 switch ((sioTopJtagidLo >> 12) & 0xFF) {
976 case 0x13:
977 /* typeId = DRX3913K_TYPE_ID */
978 state->m_hasLNA = false;
979 state->m_hasOOB = false;
980 state->m_hasATV = false;
981 state->m_hasAudio = false;
982 state->m_hasDVBT = true;
983 state->m_hasDVBC = true;
984 state->m_hasSAWSW = true;
985 state->m_hasGPIO2 = false;
986 state->m_hasGPIO1 = false;
987 state->m_hasIRQN = false;
988 break;
989 case 0x15:
990 /* typeId = DRX3915K_TYPE_ID */
991 state->m_hasLNA = false;
992 state->m_hasOOB = false;
993 state->m_hasATV = true;
994 state->m_hasAudio = false;
995 state->m_hasDVBT = true;
996 state->m_hasDVBC = false;
997 state->m_hasSAWSW = true;
998 state->m_hasGPIO2 = true;
999 state->m_hasGPIO1 = true;
1000 state->m_hasIRQN = false;
1001 break;
1002 case 0x16:
1003 /* typeId = DRX3916K_TYPE_ID */
1004 state->m_hasLNA = false;
1005 state->m_hasOOB = false;
1006 state->m_hasATV = true;
1007 state->m_hasAudio = false;
1008 state->m_hasDVBT = true;
1009 state->m_hasDVBC = false;
1010 state->m_hasSAWSW = true;
1011 state->m_hasGPIO2 = true;
1012 state->m_hasGPIO1 = true;
1013 state->m_hasIRQN = false;
1014 break;
1015 case 0x18:
1016 /* typeId = DRX3918K_TYPE_ID */
1017 state->m_hasLNA = false;
1018 state->m_hasOOB = false;
1019 state->m_hasATV = true;
1020 state->m_hasAudio = true;
1021 state->m_hasDVBT = true;
1022 state->m_hasDVBC = false;
1023 state->m_hasSAWSW = true;
1024 state->m_hasGPIO2 = true;
1025 state->m_hasGPIO1 = true;
1026 state->m_hasIRQN = false;
1027 break;
1028 case 0x21:
1029 /* typeId = DRX3921K_TYPE_ID */
1030 state->m_hasLNA = false;
1031 state->m_hasOOB = false;
1032 state->m_hasATV = true;
1033 state->m_hasAudio = true;
1034 state->m_hasDVBT = true;
1035 state->m_hasDVBC = true;
1036 state->m_hasSAWSW = true;
1037 state->m_hasGPIO2 = true;
1038 state->m_hasGPIO1 = true;
1039 state->m_hasIRQN = false;
1040 break;
1041 case 0x23:
1042 /* typeId = DRX3923K_TYPE_ID */
1043 state->m_hasLNA = false;
1044 state->m_hasOOB = false;
1045 state->m_hasATV = true;
1046 state->m_hasAudio = true;
1047 state->m_hasDVBT = true;
1048 state->m_hasDVBC = true;
1049 state->m_hasSAWSW = true;
1050 state->m_hasGPIO2 = true;
1051 state->m_hasGPIO1 = true;
1052 state->m_hasIRQN = false;
1053 break;
1054 case 0x25:
1055 /* typeId = DRX3925K_TYPE_ID */
1056 state->m_hasLNA = false;
1057 state->m_hasOOB = false;
1058 state->m_hasATV = true;
1059 state->m_hasAudio = true;
1060 state->m_hasDVBT = true;
1061 state->m_hasDVBC = true;
1062 state->m_hasSAWSW = true;
1063 state->m_hasGPIO2 = true;
1064 state->m_hasGPIO1 = true;
1065 state->m_hasIRQN = false;
1066 break;
1067 case 0x26:
1068 /* typeId = DRX3926K_TYPE_ID */
1069 state->m_hasLNA = false;
1070 state->m_hasOOB = false;
1071 state->m_hasATV = true;
1072 state->m_hasAudio = false;
1073 state->m_hasDVBT = true;
1074 state->m_hasDVBC = true;
1075 state->m_hasSAWSW = true;
1076 state->m_hasGPIO2 = true;
1077 state->m_hasGPIO1 = true;
1078 state->m_hasIRQN = false;
1079 break;
1080 default:
1081 printk(KERN_ERR "drxk: DeviceID not supported = %02x\n",
1082 ((sioTopJtagidLo >> 12) & 0xFF));
1083 status = -EINVAL;
1084 goto error2;
1085 }
1086
1087error:
1088 if (status < 0)
1089 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1090
1091error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001092 return status;
1093}
1094
1095static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1096{
1097 int status;
1098 bool powerdown_cmd;
1099
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001100 dprintk(1, "\n");
1101
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001102 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001103 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001104 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001105 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001106 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1107 msleep(1);
1108
1109 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001110 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1111 ((state->m_HICfgCtrl) &
1112 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1113 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001114 if (powerdown_cmd == false) {
1115 /* Wait until command rdy */
1116 u32 retryCount = 0;
1117 u16 waitCmd;
1118
1119 do {
1120 msleep(1);
1121 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001122 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1123 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001124 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1125 && (waitCmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001126 if (status < 0)
1127 goto error;
1128 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001129 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001130error:
1131 if (status < 0)
1132 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1133
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001134 return status;
1135}
1136
1137static int HI_CfgCommand(struct drxk_state *state)
1138{
1139 int status;
1140
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001141 dprintk(1, "\n");
1142
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001143 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001144
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001145 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1146 if (status < 0)
1147 goto error;
1148 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1149 if (status < 0)
1150 goto error;
1151 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1152 if (status < 0)
1153 goto error;
1154 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1155 if (status < 0)
1156 goto error;
1157 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1158 if (status < 0)
1159 goto error;
1160 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1161 if (status < 0)
1162 goto error;
1163 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1164 if (status < 0)
1165 goto error;
1166
1167 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1168error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001169 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001170 if (status < 0)
1171 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001172 return status;
1173}
1174
1175static int InitHI(struct drxk_state *state)
1176{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001177 dprintk(1, "\n");
1178
Oliver Endrissebc7de22011-07-03 13:49:44 -03001179 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001180 state->m_HICfgTimeout = 0x96FF;
1181 /* port/bridge/power down ctrl */
1182 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001183
Oliver Endrissebc7de22011-07-03 13:49:44 -03001184 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001185}
1186
1187static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1188{
1189 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001190 u16 sioPdrMclkCfg = 0;
1191 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001192
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001193 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001194
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001195 /* stop lock indicator process */
1196 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1197 if (status < 0)
1198 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001199
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001200 /* MPEG TS pad configuration */
1201 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1202 if (status < 0)
1203 goto error;
1204
1205 if (mpegEnable == false) {
1206 /* Set MPEG TS pads to inputmode */
1207 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1208 if (status < 0)
1209 goto error;
1210 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1211 if (status < 0)
1212 goto error;
1213 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1214 if (status < 0)
1215 goto error;
1216 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1217 if (status < 0)
1218 goto error;
1219 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1220 if (status < 0)
1221 goto error;
1222 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1223 if (status < 0)
1224 goto error;
1225 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1226 if (status < 0)
1227 goto error;
1228 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1229 if (status < 0)
1230 goto error;
1231 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1232 if (status < 0)
1233 goto error;
1234 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1235 if (status < 0)
1236 goto error;
1237 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1238 if (status < 0)
1239 goto error;
1240 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1241 if (status < 0)
1242 goto error;
1243 } else {
1244 /* Enable MPEG output */
1245 sioPdrMdxCfg =
1246 ((state->m_TSDataStrength <<
1247 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1248 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1249 SIO_PDR_MCLK_CFG_DRIVE__B) |
1250 0x0003);
1251
1252 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1253 if (status < 0)
1254 goto error;
1255 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
1256 if (status < 0)
1257 goto error;
1258 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
1259 if (status < 0)
1260 goto error;
1261 if (state->m_enableParallel == true) {
1262 /* paralel -> enable MD1 to MD7 */
1263 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001264 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001265 goto error;
1266 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001267 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001268 goto error;
1269 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001270 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001271 goto error;
1272 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001273 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001274 goto error;
1275 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001276 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001277 goto error;
1278 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1279 if (status < 0)
1280 goto error;
1281 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1282 if (status < 0)
1283 goto error;
1284 } else {
1285 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1286 SIO_PDR_MD0_CFG_DRIVE__B)
1287 | 0x0003);
1288 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001289 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001290 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001291 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001292 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001293 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001294 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001295 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001296 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001297 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001298 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001299 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001300 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001301 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001302 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001303 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001304 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001305 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001306 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001307 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001308 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001309 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001310 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001311 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001312 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001313 goto error;
1314 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001315 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001316 goto error;
1317 }
1318 /* Enable MB output over MPEG pads and ctl input */
1319 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1320 if (status < 0)
1321 goto error;
1322 /* Write nomagic word to enable pdr reg write */
1323 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1324error:
1325 if (status < 0)
1326 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001327 return status;
1328}
1329
1330static int MPEGTSDisable(struct drxk_state *state)
1331{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001332 dprintk(1, "\n");
1333
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001334 return MPEGTSConfigurePins(state, false);
1335}
1336
1337static int BLChainCmd(struct drxk_state *state,
1338 u16 romOffset, u16 nrOfElements, u32 timeOut)
1339{
1340 u16 blStatus = 0;
1341 int status;
1342 unsigned long end;
1343
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001344 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001345 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001346 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1347 if (status < 0)
1348 goto error;
1349 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1350 if (status < 0)
1351 goto error;
1352 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1353 if (status < 0)
1354 goto error;
1355 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1356 if (status < 0)
1357 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001358
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001359 end = jiffies + msecs_to_jiffies(timeOut);
1360 do {
1361 msleep(1);
1362 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1363 if (status < 0)
1364 goto error;
1365 } while ((blStatus == 0x1) &&
1366 ((time_is_after_jiffies(end))));
1367
1368 if (blStatus == 0x1) {
1369 printk(KERN_ERR "drxk: SIO not ready\n");
1370 status = -EINVAL;
1371 goto error2;
1372 }
1373error:
1374 if (status < 0)
1375 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1376error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001377 mutex_unlock(&state->mutex);
1378 return status;
1379}
1380
1381
1382static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001383 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001384{
1385 const u8 *pSrc = pMCImage;
1386 u16 Flags;
1387 u16 Drain;
1388 u32 Address;
1389 u16 nBlocks;
1390 u16 BlockSize;
1391 u16 BlockCRC;
1392 u32 offset = 0;
1393 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001394 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001395
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001396 dprintk(1, "\n");
1397
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001398 /* down the drain (we don care about MAGIC_WORD) */
1399 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001400 pSrc += sizeof(u16);
1401 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001402 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001403 pSrc += sizeof(u16);
1404 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001405
1406 for (i = 0; i < nBlocks; i += 1) {
1407 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001408 (pSrc[2] << 8) | pSrc[3];
1409 pSrc += sizeof(u32);
1410 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001411
1412 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001413 pSrc += sizeof(u16);
1414 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001415
1416 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001417 pSrc += sizeof(u16);
1418 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001419
1420 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001421 pSrc += sizeof(u16);
1422 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001423
1424 if (offset + BlockSize > Length) {
1425 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1426 return -EINVAL;
1427 }
1428
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001429 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001430 if (status < 0) {
1431 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001432 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001433 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001434 pSrc += BlockSize;
1435 offset += BlockSize;
1436 }
1437 return status;
1438}
1439
1440static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1441{
1442 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001443 u16 data = 0;
1444 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001445 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1446 unsigned long end;
1447
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001448 dprintk(1, "\n");
1449
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001450 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001451 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001452 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1453 }
1454
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001455 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1456 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001457 /* tokenring already has correct status */
1458 return status;
1459 }
1460 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001461 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001462
Oliver Endrissebc7de22011-07-03 13:49:44 -03001463 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001464 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001465 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001466 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001467 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001468 msleep(1);
1469 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001470 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001471 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001472 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001473 }
1474 return status;
1475}
1476
1477static int MPEGTSStop(struct drxk_state *state)
1478{
1479 int status = 0;
1480 u16 fecOcSncMode = 0;
1481 u16 fecOcIprMode = 0;
1482
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001483 dprintk(1, "\n");
1484
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001485 /* Gracefull shutdown (byte boundaries) */
1486 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1487 if (status < 0)
1488 goto error;
1489 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1490 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1491 if (status < 0)
1492 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001493
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001494 /* Suppress MCLK during absence of data */
1495 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1496 if (status < 0)
1497 goto error;
1498 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1499 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1500
1501error:
1502 if (status < 0)
1503 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1504
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001505 return status;
1506}
1507
1508static int scu_command(struct drxk_state *state,
1509 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001510 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001511{
1512#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1513#error DRXK register mapping no longer compatible with this routine!
1514#endif
1515 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001516 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001517 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001518 u8 buffer[34];
1519 int cnt = 0, ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001520
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001521 dprintk(1, "\n");
1522
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001523 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1524 ((resultLen > 0) && (result == NULL)))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001525 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001526
1527 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001528
1529 /* assume that the command register is ready
1530 since it is checked afterwards */
1531 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1532 buffer[cnt++] = (parameter[ii] & 0xFF);
1533 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1534 }
1535 buffer[cnt++] = (cmd & 0xFF);
1536 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1537
1538 write_block(state, SCU_RAM_PARAM_0__A -
1539 (parameterLen - 1), cnt, buffer);
1540 /* Wait until SCU has processed command */
1541 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001542 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001543 msleep(1);
1544 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1545 if (status < 0)
1546 goto error;
1547 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1548 if (curCmd != DRX_SCU_READY) {
1549 printk(KERN_ERR "drxk: SCU not ready\n");
1550 status = -EIO;
1551 goto error2;
1552 }
1553 /* read results */
1554 if ((resultLen > 0) && (result != NULL)) {
1555 s16 err;
1556 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001557
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001558 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1559 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001560 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001561 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001562 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001563
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001564 /* Check if an error was reported by SCU */
1565 err = (s16)result[0];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001566
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001567 /* check a few fixed error codes */
1568 if (err == SCU_RESULT_UNKSTD) {
1569 printk(KERN_ERR "drxk: SCU_RESULT_UNKSTD\n");
1570 status = -EINVAL;
1571 goto error2;
1572 } else if (err == SCU_RESULT_UNKCMD) {
1573 printk(KERN_ERR "drxk: SCU_RESULT_UNKCMD\n");
1574 status = -EINVAL;
1575 goto error2;
1576 } else if (err < 0) {
1577 /*
1578 * here it is assumed that a nagative result means
1579 * error, and positive no error
1580 */
1581 printk(KERN_ERR "drxk: %s ERROR: %d\n", __func__, err);
1582 status = -EINVAL;
1583 goto error2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001584 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001585 }
1586
1587error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001588 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001589 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001590
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001591error2:
1592 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001593 return status;
1594}
1595
1596static int SetIqmAf(struct drxk_state *state, bool active)
1597{
1598 u16 data = 0;
1599 int status;
1600
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001601 dprintk(1, "\n");
1602
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001603 /* Configure IQM */
1604 status = read16(state, IQM_AF_STDBY__A, &data);
1605 if (status < 0)
1606 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001607
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001608 if (!active) {
1609 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1610 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1611 | IQM_AF_STDBY_STDBY_PD_STANDBY
1612 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1613 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1614 } else {
1615 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1616 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1617 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1618 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1619 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1620 );
1621 }
1622 status = write16(state, IQM_AF_STDBY__A, data);
1623
1624error:
1625 if (status < 0)
1626 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001627 return status;
1628}
1629
Oliver Endrissebc7de22011-07-03 13:49:44 -03001630static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001631{
1632 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001633 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001634
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001635 dprintk(1, "\n");
1636
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001637 /* Check arguments */
1638 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001639 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001640
1641 switch (*mode) {
1642 case DRX_POWER_UP:
1643 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1644 break;
1645 case DRXK_POWER_DOWN_OFDM:
1646 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1647 break;
1648 case DRXK_POWER_DOWN_CORE:
1649 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1650 break;
1651 case DRXK_POWER_DOWN_PLL:
1652 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1653 break;
1654 case DRX_POWER_DOWN:
1655 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1656 break;
1657 default:
1658 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001659 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001660 break;
1661 }
1662
1663 /* If already in requested power mode, do nothing */
1664 if (state->m_currentPowerMode == *mode)
1665 return 0;
1666
1667 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001668 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001669 status = PowerUpDevice(state);
1670 if (status < 0)
1671 goto error;
1672 status = DVBTEnableOFDMTokenRing(state, true);
1673 if (status < 0)
1674 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001675 }
1676
1677 if (*mode == DRX_POWER_UP) {
1678 /* Restore analog & pin configuartion */
1679 } else {
1680 /* Power down to requested mode */
1681 /* Backup some register settings */
1682 /* Set pins with possible pull-ups connected
1683 to them in input mode */
1684 /* Analog power down */
1685 /* ADC power down */
1686 /* Power down device */
1687 /* stop all comm_exec */
1688 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001689 switch (state->m_OperationMode) {
1690 case OM_DVBT:
1691 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001692 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001693 goto error;
1694 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001695 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001696 goto error;
1697 break;
1698 case OM_QAM_ITU_A:
1699 case OM_QAM_ITU_C:
1700 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001701 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001702 goto error;
1703 status = PowerDownQAM(state);
1704 if (status < 0)
1705 goto error;
1706 break;
1707 default:
1708 break;
1709 }
1710 status = DVBTEnableOFDMTokenRing(state, false);
1711 if (status < 0)
1712 goto error;
1713 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1714 if (status < 0)
1715 goto error;
1716 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1717 if (status < 0)
1718 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001719
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001720 if (*mode != DRXK_POWER_DOWN_OFDM) {
1721 state->m_HICfgCtrl |=
1722 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1723 status = HI_CfgCommand(state);
1724 if (status < 0)
1725 goto error;
1726 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001727 }
1728 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001729
1730error:
1731 if (status < 0)
1732 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1733
Oliver Endrissebc7de22011-07-03 13:49:44 -03001734 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001735}
1736
1737static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1738{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001739 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001740 u16 cmdResult = 0;
1741 u16 data = 0;
1742 int status;
1743
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001744 dprintk(1, "\n");
1745
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001746 status = read16(state, SCU_COMM_EXEC__A, &data);
1747 if (status < 0)
1748 goto error;
1749 if (data == SCU_COMM_EXEC_ACTIVE) {
1750 /* Send OFDM stop command */
1751 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001752 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001753 goto error;
1754 /* Send OFDM reset command */
1755 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1756 if (status < 0)
1757 goto error;
1758 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001759
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001760 /* Reset datapath for OFDM, processors first */
1761 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1762 if (status < 0)
1763 goto error;
1764 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1765 if (status < 0)
1766 goto error;
1767 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1768 if (status < 0)
1769 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001770
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001771 /* powerdown AFE */
1772 status = SetIqmAf(state, false);
1773 if (status < 0)
1774 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001775
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001776 /* powerdown to OFDM mode */
1777 if (setPowerMode) {
1778 status = CtrlPowerMode(state, &powerMode);
1779 if (status < 0)
1780 goto error;
1781 }
1782error:
1783 if (status < 0)
1784 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001785 return status;
1786}
1787
Oliver Endrissebc7de22011-07-03 13:49:44 -03001788static int SetOperationMode(struct drxk_state *state,
1789 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001790{
1791 int status = 0;
1792
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001793 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001794 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001795 Stop and power down previous standard
1796 TODO investigate total power down instead of partial
1797 power down depending on "previous" standard.
1798 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001799
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001800 /* disable HW lock indicator */
1801 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1802 if (status < 0)
1803 goto error;
1804
1805 if (state->m_OperationMode != oMode) {
1806 switch (state->m_OperationMode) {
1807 /* OM_NONE was added for start up */
1808 case OM_NONE:
1809 break;
1810 case OM_DVBT:
1811 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001812 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001813 goto error;
1814 status = PowerDownDVBT(state, true);
1815 if (status < 0)
1816 goto error;
1817 state->m_OperationMode = OM_NONE;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001818 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001819 case OM_QAM_ITU_A: /* fallthrough */
1820 case OM_QAM_ITU_C:
1821 status = MPEGTSStop(state);
1822 if (status < 0)
1823 goto error;
1824 status = PowerDownQAM(state);
1825 if (status < 0)
1826 goto error;
1827 state->m_OperationMode = OM_NONE;
1828 break;
1829 case OM_QAM_ITU_B:
1830 default:
1831 status = -EINVAL;
1832 goto error;
1833 }
1834
1835 /*
1836 Power up new standard
1837 */
1838 switch (oMode) {
1839 case OM_DVBT:
Mauro Carvalho Chehabd6a05402011-07-10 13:07:36 -03001840 state->m_OperationMode = oMode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001841 status = SetDVBTStandard(state, oMode);
1842 if (status < 0)
1843 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001844 break;
1845 case OM_QAM_ITU_A: /* fallthrough */
1846 case OM_QAM_ITU_C:
Mauro Carvalho Chehabd6a05402011-07-10 13:07:36 -03001847 state->m_OperationMode = oMode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001848 status = SetQAMStandard(state, oMode);
1849 if (status < 0)
1850 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001851 break;
1852 case OM_QAM_ITU_B:
1853 default:
1854 status = -EINVAL;
1855 }
1856 }
1857error:
1858 if (status < 0)
1859 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1860 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001861}
1862
1863static int Start(struct drxk_state *state, s32 offsetFreq,
1864 s32 IntermediateFrequency)
1865{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001866 int status = -EINVAL;
1867
1868 u16 IFreqkHz;
1869 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001870
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001871 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001872 if (state->m_DrxkState != DRXK_STOPPED &&
1873 state->m_DrxkState != DRXK_DTV_STARTED)
1874 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001875
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001876 state->m_bMirrorFreqSpect = (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001877
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001878 if (IntermediateFrequency < 0) {
1879 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1880 IntermediateFrequency = -IntermediateFrequency;
1881 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001882
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001883 switch (state->m_OperationMode) {
1884 case OM_QAM_ITU_A:
1885 case OM_QAM_ITU_C:
1886 IFreqkHz = (IntermediateFrequency / 1000);
1887 status = SetQAM(state, IFreqkHz, OffsetkHz);
1888 if (status < 0)
1889 goto error;
1890 state->m_DrxkState = DRXK_DTV_STARTED;
1891 break;
1892 case OM_DVBT:
1893 IFreqkHz = (IntermediateFrequency / 1000);
1894 status = MPEGTSStop(state);
1895 if (status < 0)
1896 goto error;
1897 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1898 if (status < 0)
1899 goto error;
1900 status = DVBTStart(state);
1901 if (status < 0)
1902 goto error;
1903 state->m_DrxkState = DRXK_DTV_STARTED;
1904 break;
1905 default:
1906 break;
1907 }
1908error:
1909 if (status < 0)
1910 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001911 return status;
1912}
1913
1914static int ShutDown(struct drxk_state *state)
1915{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001916 dprintk(1, "\n");
1917
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001918 MPEGTSStop(state);
1919 return 0;
1920}
1921
Oliver Endrissebc7de22011-07-03 13:49:44 -03001922static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1923 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001924{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001925 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001926
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001927 dprintk(1, "\n");
1928
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001929 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001930 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001931
1932 *pLockStatus = NOT_LOCKED;
1933
1934 /* define the SCU command code */
1935 switch (state->m_OperationMode) {
1936 case OM_QAM_ITU_A:
1937 case OM_QAM_ITU_B:
1938 case OM_QAM_ITU_C:
1939 status = GetQAMLockStatus(state, pLockStatus);
1940 break;
1941 case OM_DVBT:
1942 status = GetDVBTLockStatus(state, pLockStatus);
1943 break;
1944 default:
1945 break;
1946 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001947error:
1948 if (status < 0)
1949 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001950 return status;
1951}
1952
1953static int MPEGTSStart(struct drxk_state *state)
1954{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001955 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001956
1957 u16 fecOcSncMode = 0;
1958
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001959 /* Allow OC to sync again */
1960 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1961 if (status < 0)
1962 goto error;
1963 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1964 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1965 if (status < 0)
1966 goto error;
1967 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1968error:
1969 if (status < 0)
1970 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001971 return status;
1972}
1973
1974static int MPEGTSDtoInit(struct drxk_state *state)
1975{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001976 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001977
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001978 dprintk(1, "\n");
1979
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001980 /* Rate integration settings */
1981 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1982 if (status < 0)
1983 goto error;
1984 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1985 if (status < 0)
1986 goto error;
1987 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1988 if (status < 0)
1989 goto error;
1990 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1991 if (status < 0)
1992 goto error;
1993 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
1994 if (status < 0)
1995 goto error;
1996 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
1997 if (status < 0)
1998 goto error;
1999 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2000 if (status < 0)
2001 goto error;
2002 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2003 if (status < 0)
2004 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002005
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002006 /* Additional configuration */
2007 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2008 if (status < 0)
2009 goto error;
2010 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2011 if (status < 0)
2012 goto error;
2013 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2014error:
2015 if (status < 0)
2016 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2017
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002018 return status;
2019}
2020
Oliver Endrissebc7de22011-07-03 13:49:44 -03002021static int MPEGTSDtoSetup(struct drxk_state *state,
2022 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002023{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002024 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002025
Oliver Endrissebc7de22011-07-03 13:49:44 -03002026 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2027 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2028 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2029 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2030 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2031 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2032 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002033 u16 fecOcTmdMode = 0;
2034 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002035 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002036 bool staticCLK = false;
2037
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002038 dprintk(1, "\n");
2039
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002040 /* Check insertion of the Reed-Solomon parity bytes */
2041 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2042 if (status < 0)
2043 goto error;
2044 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2045 if (status < 0)
2046 goto error;
2047 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2048 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2049 if (state->m_insertRSByte == true) {
2050 /* enable parity symbol forward */
2051 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2052 /* MVAL disable during parity bytes */
2053 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2054 /* TS burst length to 204 */
2055 fecOcDtoBurstLen = 204;
2056 }
2057
2058 /* Check serial or parrallel output */
2059 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2060 if (state->m_enableParallel == false) {
2061 /* MPEG data output is serial -> set ipr_mode[0] */
2062 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2063 }
2064
2065 switch (oMode) {
2066 case OM_DVBT:
2067 maxBitRate = state->m_DVBTBitrate;
2068 fecOcTmdMode = 3;
2069 fecOcRcnCtlRate = 0xC00000;
2070 staticCLK = state->m_DVBTStaticCLK;
2071 break;
2072 case OM_QAM_ITU_A: /* fallthrough */
2073 case OM_QAM_ITU_C:
2074 fecOcTmdMode = 0x0004;
2075 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2076 maxBitRate = state->m_DVBCBitrate;
2077 staticCLK = state->m_DVBCStaticCLK;
2078 break;
2079 default:
2080 status = -EINVAL;
2081 } /* switch (standard) */
2082 if (status < 0)
2083 goto error;
2084
2085 /* Configure DTO's */
2086 if (staticCLK) {
2087 u32 bitRate = 0;
2088
2089 /* Rational DTO for MCLK source (static MCLK rate),
2090 Dynamic DTO for optimal grouping
2091 (avoid intra-packet gaps),
2092 DTO offset enable to sync TS burst with MSTRT */
2093 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2094 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2095 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2096 FEC_OC_FCT_MODE_VIRT_ENA__M);
2097
2098 /* Check user defined bitrate */
2099 bitRate = maxBitRate;
2100 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2101 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002102 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002103 /* Rational DTO period:
2104 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002105
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002106 Result should be floored,
2107 to make sure >= requested bitrate
2108 */
2109 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2110 * 1000) / bitRate);
2111 if (fecOcDtoPeriod <= 2)
2112 fecOcDtoPeriod = 0;
2113 else
2114 fecOcDtoPeriod -= 2;
2115 fecOcTmdIntUpdRate = 8;
2116 } else {
2117 /* (commonAttr->staticCLK == false) => dynamic mode */
2118 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2119 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2120 fecOcTmdIntUpdRate = 5;
2121 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002122
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002123 /* Write appropriate registers with requested configuration */
2124 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2125 if (status < 0)
2126 goto error;
2127 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2128 if (status < 0)
2129 goto error;
2130 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2131 if (status < 0)
2132 goto error;
2133 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2134 if (status < 0)
2135 goto error;
2136 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2137 if (status < 0)
2138 goto error;
2139 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2140 if (status < 0)
2141 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002142
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002143 /* Rate integration settings */
2144 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2145 if (status < 0)
2146 goto error;
2147 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2148 if (status < 0)
2149 goto error;
2150 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2151error:
2152 if (status < 0)
2153 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002154 return status;
2155}
2156
2157static int MPEGTSConfigurePolarity(struct drxk_state *state)
2158{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002159 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002160
2161 /* Data mask for the output data byte */
2162 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002163 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2164 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2165 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2166 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002167
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002168 dprintk(1, "\n");
2169
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002170 /* Control selective inversion of output bits */
2171 fecOcRegIprInvert &= (~(InvertDataMask));
2172 if (state->m_invertDATA == true)
2173 fecOcRegIprInvert |= InvertDataMask;
2174 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2175 if (state->m_invertERR == true)
2176 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2177 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2178 if (state->m_invertSTR == true)
2179 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2180 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2181 if (state->m_invertVAL == true)
2182 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2183 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2184 if (state->m_invertCLK == true)
2185 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002186
2187 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002188}
2189
2190#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2191
2192static int SetAgcRf(struct drxk_state *state,
2193 struct SCfgAgc *pAgcCfg, bool isDTV)
2194{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002195 int status = -EINVAL;
2196 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002197 struct SCfgAgc *pIfAgcSettings;
2198
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002199 dprintk(1, "\n");
2200
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002201 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002202 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002203
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002204 switch (pAgcCfg->ctrlMode) {
2205 case DRXK_AGC_CTRL_AUTO:
2206 /* Enable RF AGC DAC */
2207 status = read16(state, IQM_AF_STDBY__A, &data);
2208 if (status < 0)
2209 goto error;
2210 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2211 status = write16(state, IQM_AF_STDBY__A, data);
2212 if (status < 0)
2213 goto error;
2214 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2215 if (status < 0)
2216 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002217
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002218 /* Enable SCU RF AGC loop */
2219 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002220
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002221 /* Polarity */
2222 if (state->m_RfAgcPol)
2223 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2224 else
2225 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2226 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2227 if (status < 0)
2228 goto error;
2229
2230 /* Set speed (using complementary reduction value) */
2231 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2232 if (status < 0)
2233 goto error;
2234
2235 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2236 data |= (~(pAgcCfg->speed <<
2237 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2238 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2239
2240 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2241 if (status < 0)
2242 goto error;
2243
2244 if (IsDVBT(state))
2245 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2246 else if (IsQAM(state))
2247 pIfAgcSettings = &state->m_qamIfAgcCfg;
2248 else
2249 pIfAgcSettings = &state->m_atvIfAgcCfg;
2250 if (pIfAgcSettings == NULL) {
2251 status = -EINVAL;
2252 goto error;
2253 }
2254
2255 /* Set TOP, only if IF-AGC is in AUTO mode */
2256 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2257 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002258 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002259 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002260
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002261 /* Cut-Off current */
2262 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2263 if (status < 0)
2264 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002265
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002266 /* Max. output level */
2267 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2268 if (status < 0)
2269 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002270
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002271 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002272
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002273 case DRXK_AGC_CTRL_USER:
2274 /* Enable RF AGC DAC */
2275 status = read16(state, IQM_AF_STDBY__A, &data);
2276 if (status < 0)
2277 goto error;
2278 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2279 status = write16(state, IQM_AF_STDBY__A, data);
2280 if (status < 0)
2281 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002282
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002283 /* Disable SCU RF AGC loop */
2284 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2285 if (status < 0)
2286 goto error;
2287 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2288 if (state->m_RfAgcPol)
2289 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2290 else
2291 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2292 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2293 if (status < 0)
2294 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002295
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002296 /* SCU c.o.c. to 0, enabling full control range */
2297 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2298 if (status < 0)
2299 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002300
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002301 /* Write value to output pin */
2302 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2303 if (status < 0)
2304 goto error;
2305 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002306
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002307 case DRXK_AGC_CTRL_OFF:
2308 /* Disable RF AGC DAC */
2309 status = read16(state, IQM_AF_STDBY__A, &data);
2310 if (status < 0)
2311 goto error;
2312 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2313 status = write16(state, IQM_AF_STDBY__A, data);
2314 if (status < 0)
2315 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002316
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002317 /* Disable SCU RF AGC loop */
2318 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2319 if (status < 0)
2320 goto error;
2321 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2322 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2323 if (status < 0)
2324 goto error;
2325 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002326
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002327 default:
2328 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002329
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002330 }
2331error:
2332 if (status < 0)
2333 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002334 return status;
2335}
2336
2337#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2338
Oliver Endrissebc7de22011-07-03 13:49:44 -03002339static int SetAgcIf(struct drxk_state *state,
2340 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002341{
2342 u16 data = 0;
2343 int status = 0;
2344 struct SCfgAgc *pRfAgcSettings;
2345
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002346 dprintk(1, "\n");
2347
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002348 switch (pAgcCfg->ctrlMode) {
2349 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002350
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002351 /* Enable IF AGC DAC */
2352 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002353 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002354 goto error;
2355 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2356 status = write16(state, IQM_AF_STDBY__A, data);
2357 if (status < 0)
2358 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002359
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002360 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2361 if (status < 0)
2362 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002363
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002364 /* Enable SCU IF AGC loop */
2365 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2366
2367 /* Polarity */
2368 if (state->m_IfAgcPol)
2369 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2370 else
2371 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2372 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2373 if (status < 0)
2374 goto error;
2375
2376 /* Set speed (using complementary reduction value) */
2377 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2378 if (status < 0)
2379 goto error;
2380 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2381 data |= (~(pAgcCfg->speed <<
2382 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2383 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2384
2385 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2386 if (status < 0)
2387 goto error;
2388
2389 if (IsQAM(state))
2390 pRfAgcSettings = &state->m_qamRfAgcCfg;
2391 else
2392 pRfAgcSettings = &state->m_atvRfAgcCfg;
2393 if (pRfAgcSettings == NULL)
2394 return -1;
2395 /* Restore TOP */
2396 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2397 if (status < 0)
2398 goto error;
2399 break;
2400
2401 case DRXK_AGC_CTRL_USER:
2402
2403 /* Enable IF AGC DAC */
2404 status = read16(state, IQM_AF_STDBY__A, &data);
2405 if (status < 0)
2406 goto error;
2407 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2408 status = write16(state, IQM_AF_STDBY__A, data);
2409 if (status < 0)
2410 goto error;
2411
2412 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2413 if (status < 0)
2414 goto error;
2415
2416 /* Disable SCU IF AGC loop */
2417 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2418
2419 /* Polarity */
2420 if (state->m_IfAgcPol)
2421 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2422 else
2423 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2424 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2425 if (status < 0)
2426 goto error;
2427
2428 /* Write value to output pin */
2429 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2430 if (status < 0)
2431 goto error;
2432 break;
2433
2434 case DRXK_AGC_CTRL_OFF:
2435
2436 /* Disable If AGC DAC */
2437 status = read16(state, IQM_AF_STDBY__A, &data);
2438 if (status < 0)
2439 goto error;
2440 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2441 status = write16(state, IQM_AF_STDBY__A, data);
2442 if (status < 0)
2443 goto error;
2444
2445 /* Disable SCU IF AGC loop */
2446 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2447 if (status < 0)
2448 goto error;
2449 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2450 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2451 if (status < 0)
2452 goto error;
2453 break;
2454 } /* switch (agcSettingsIf->ctrlMode) */
2455
2456 /* always set the top to support
2457 configurations without if-loop */
2458 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2459error:
2460 if (status < 0)
2461 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002462 return status;
2463}
2464
2465static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2466{
2467 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002468 int status;
2469 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002470
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002471 dprintk(1, "\n");
2472
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002473 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2474 if (status < 0) {
2475 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2476 return status;
2477 }
2478
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002479 *pValue = 0;
2480
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002481 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2482 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2483 if (Level < 14000)
2484 *pValue = (14000 - Level) / 4;
2485 else
2486 *pValue = 0;
2487
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002488 return status;
2489}
2490
Oliver Endrissebc7de22011-07-03 13:49:44 -03002491static int GetQAMSignalToNoise(struct drxk_state *state,
2492 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002493{
2494 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002495 u16 qamSlErrPower = 0; /* accum. error between
2496 raw and sliced symbols */
2497 u32 qamSlSigPower = 0; /* used for MER, depends of
2498 QAM constellation */
2499 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002500
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002501 dprintk(1, "\n");
2502
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002503 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002504
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002505 /* get the register value needed for MER */
2506 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2507 if (status < 0) {
2508 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2509 return -EINVAL;
2510 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002511
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002512 switch (state->param.u.qam.modulation) {
2513 case QAM_16:
2514 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2515 break;
2516 case QAM_32:
2517 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2518 break;
2519 case QAM_64:
2520 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2521 break;
2522 case QAM_128:
2523 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2524 break;
2525 default:
2526 case QAM_256:
2527 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2528 break;
2529 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002530
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002531 if (qamSlErrPower > 0) {
2532 qamSlMer = Log10Times100(qamSlSigPower) -
2533 Log10Times100((u32) qamSlErrPower);
2534 }
2535 *pSignalToNoise = qamSlMer;
2536
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002537 return status;
2538}
2539
Oliver Endrissebc7de22011-07-03 13:49:44 -03002540static int GetDVBTSignalToNoise(struct drxk_state *state,
2541 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002542{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002543 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002544 u16 regData = 0;
2545 u32 EqRegTdSqrErrI = 0;
2546 u32 EqRegTdSqrErrQ = 0;
2547 u16 EqRegTdSqrErrExp = 0;
2548 u16 EqRegTdTpsPwrOfs = 0;
2549 u16 EqRegTdReqSmbCnt = 0;
2550 u32 tpsCnt = 0;
2551 u32 SqrErrIQ = 0;
2552 u32 a = 0;
2553 u32 b = 0;
2554 u32 c = 0;
2555 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002556 u16 transmissionParams = 0;
2557
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002558 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002559
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002560 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2561 if (status < 0)
2562 goto error;
2563 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2564 if (status < 0)
2565 goto error;
2566 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2567 if (status < 0)
2568 goto error;
2569 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2570 if (status < 0)
2571 goto error;
2572 /* Extend SQR_ERR_I operational range */
2573 EqRegTdSqrErrI = (u32) regData;
2574 if ((EqRegTdSqrErrExp > 11) &&
2575 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2576 EqRegTdSqrErrI += 0x00010000UL;
2577 }
2578 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2579 if (status < 0)
2580 goto error;
2581 /* Extend SQR_ERR_Q operational range */
2582 EqRegTdSqrErrQ = (u32) regData;
2583 if ((EqRegTdSqrErrExp > 11) &&
2584 (EqRegTdSqrErrQ < 0x00000FFFUL))
2585 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002586
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002587 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2588 if (status < 0)
2589 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002590
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002591 /* Check input data for MER */
2592
2593 /* MER calculation (in 0.1 dB) without math.h */
2594 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2595 iMER = 0;
2596 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2597 /* No error at all, this must be the HW reset value
2598 * Apparently no first measurement yet
2599 * Set MER to 0.0 */
2600 iMER = 0;
2601 } else {
2602 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2603 EqRegTdSqrErrExp;
2604 if ((transmissionParams &
2605 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2606 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2607 tpsCnt = 17;
2608 else
2609 tpsCnt = 68;
2610
2611 /* IMER = 100 * log10 (x)
2612 where x = (EqRegTdTpsPwrOfs^2 *
2613 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2614
2615 => IMER = a + b -c
2616 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2617 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2618 c = 100 * log10 (SqrErrIQ)
2619 */
2620
2621 /* log(x) x = 9bits * 9bits->18 bits */
2622 a = Log10Times100(EqRegTdTpsPwrOfs *
2623 EqRegTdTpsPwrOfs);
2624 /* log(x) x = 16bits * 7bits->23 bits */
2625 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2626 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2627 c = Log10Times100(SqrErrIQ);
2628
2629 iMER = a + b;
2630 /* No negative MER, clip to zero */
2631 if (iMER > c)
2632 iMER -= c;
2633 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002634 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002635 }
2636 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002637
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002638error:
2639 if (status < 0)
2640 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002641 return status;
2642}
2643
2644static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2645{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002646 dprintk(1, "\n");
2647
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002648 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002649 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002650 case OM_DVBT:
2651 return GetDVBTSignalToNoise(state, pSignalToNoise);
2652 case OM_QAM_ITU_A:
2653 case OM_QAM_ITU_C:
2654 return GetQAMSignalToNoise(state, pSignalToNoise);
2655 default:
2656 break;
2657 }
2658 return 0;
2659}
2660
2661#if 0
2662static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2663{
2664 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2665 int status = 0;
2666
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002667 dprintk(1, "\n");
2668
Oliver Endrissebc7de22011-07-03 13:49:44 -03002669 static s32 QE_SN[] = {
2670 51, /* QPSK 1/2 */
2671 69, /* QPSK 2/3 */
2672 79, /* QPSK 3/4 */
2673 89, /* QPSK 5/6 */
2674 97, /* QPSK 7/8 */
2675 108, /* 16-QAM 1/2 */
2676 131, /* 16-QAM 2/3 */
2677 146, /* 16-QAM 3/4 */
2678 156, /* 16-QAM 5/6 */
2679 160, /* 16-QAM 7/8 */
2680 165, /* 64-QAM 1/2 */
2681 187, /* 64-QAM 2/3 */
2682 202, /* 64-QAM 3/4 */
2683 216, /* 64-QAM 5/6 */
2684 225, /* 64-QAM 7/8 */
2685 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002686
2687 *pQuality = 0;
2688
2689 do {
2690 s32 SignalToNoise = 0;
2691 u16 Constellation = 0;
2692 u16 CodeRate = 0;
2693 u32 SignalToNoiseRel;
2694 u32 BERQuality;
2695
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002696 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2697 if (status < 0)
2698 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002699 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002700 if (status < 0)
2701 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002702 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2703
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002704 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002705 if (status < 0)
2706 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002707 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2708
2709 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2710 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2711 break;
2712 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002713 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002714 BERQuality = 100;
2715
Oliver Endrissebc7de22011-07-03 13:49:44 -03002716 if (SignalToNoiseRel < -70)
2717 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002718 else if (SignalToNoiseRel < 30)
2719 *pQuality = ((SignalToNoiseRel + 70) *
2720 BERQuality) / 100;
2721 else
2722 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002723 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002724 return 0;
2725};
2726
Oliver Endrissebc7de22011-07-03 13:49:44 -03002727static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002728{
2729 int status = 0;
2730 *pQuality = 0;
2731
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002732 dprintk(1, "\n");
2733
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002734 do {
2735 u32 SignalToNoise = 0;
2736 u32 BERQuality = 100;
2737 u32 SignalToNoiseRel = 0;
2738
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002739 status = GetQAMSignalToNoise(state, &SignalToNoise);
2740 if (status < 0)
2741 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002742
Oliver Endrissebc7de22011-07-03 13:49:44 -03002743 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002744 case QAM_16:
2745 SignalToNoiseRel = SignalToNoise - 200;
2746 break;
2747 case QAM_32:
2748 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002749 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002750 case QAM_64:
2751 SignalToNoiseRel = SignalToNoise - 260;
2752 break;
2753 case QAM_128:
2754 SignalToNoiseRel = SignalToNoise - 290;
2755 break;
2756 default:
2757 case QAM_256:
2758 SignalToNoiseRel = SignalToNoise - 320;
2759 break;
2760 }
2761
2762 if (SignalToNoiseRel < -70)
2763 *pQuality = 0;
2764 else if (SignalToNoiseRel < 30)
2765 *pQuality = ((SignalToNoiseRel + 70) *
2766 BERQuality) / 100;
2767 else
2768 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002769 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002770
2771 return status;
2772}
2773
2774static int GetQuality(struct drxk_state *state, s32 *pQuality)
2775{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002776 dprintk(1, "\n");
2777
Oliver Endrissebc7de22011-07-03 13:49:44 -03002778 switch (state->m_OperationMode) {
2779 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002780 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002781 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002782 return GetDVBCQuality(state, pQuality);
2783 default:
2784 break;
2785 }
2786
2787 return 0;
2788}
2789#endif
2790
2791/* Free data ram in SIO HI */
2792#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2793#define SIO_HI_RA_RAM_USR_END__A 0x420060
2794
2795#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2796#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2797#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2798#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2799
2800#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2801#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2802#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2803
2804static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2805{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002806 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002807
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002808 dprintk(1, "\n");
2809
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002810 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002811 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002812 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002813 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002814
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002815 if (state->no_i2c_bridge)
2816 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002817
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002818 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2819 if (status < 0)
2820 goto error;
2821 if (bEnableBridge) {
2822 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002823 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002824 goto error;
2825 } else {
2826 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2827 if (status < 0)
2828 goto error;
2829 }
2830
2831 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2832
2833error:
2834 if (status < 0)
2835 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002836 return status;
2837}
2838
Oliver Endrissebc7de22011-07-03 13:49:44 -03002839static int SetPreSaw(struct drxk_state *state,
2840 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002841{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002842 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002843
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002844 dprintk(1, "\n");
2845
Oliver Endrissebc7de22011-07-03 13:49:44 -03002846 if ((pPreSawCfg == NULL)
2847 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002848 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002849
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002850 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002851error:
2852 if (status < 0)
2853 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002854 return status;
2855}
2856
2857static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002858 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002859{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002860 u16 blStatus = 0;
2861 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2862 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2863 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002864 unsigned long end;
2865
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002866 dprintk(1, "\n");
2867
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002868 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002869 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2870 if (status < 0)
2871 goto error;
2872 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2873 if (status < 0)
2874 goto error;
2875 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2876 if (status < 0)
2877 goto error;
2878 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2879 if (status < 0)
2880 goto error;
2881 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2882 if (status < 0)
2883 goto error;
2884 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2885 if (status < 0)
2886 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002887
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002888 end = jiffies + msecs_to_jiffies(timeOut);
2889 do {
2890 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2891 if (status < 0)
2892 goto error;
2893 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2894 if (blStatus == 0x1) {
2895 printk(KERN_ERR "drxk: SIO not ready\n");
2896 status = -EINVAL;
2897 goto error2;
2898 }
2899error:
2900 if (status < 0)
2901 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2902error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002903 mutex_unlock(&state->mutex);
2904 return status;
2905
2906}
2907
Oliver Endrissebc7de22011-07-03 13:49:44 -03002908static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002909{
2910 u16 data = 0;
2911 int status;
2912
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002913 dprintk(1, "\n");
2914
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002915 /* Start measurement */
2916 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2917 if (status < 0)
2918 goto error;
2919 status = write16(state, IQM_AF_START_LOCK__A, 1);
2920 if (status < 0)
2921 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002922
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002923 *count = 0;
2924 status = read16(state, IQM_AF_PHASE0__A, &data);
2925 if (status < 0)
2926 goto error;
2927 if (data == 127)
2928 *count = *count + 1;
2929 status = read16(state, IQM_AF_PHASE1__A, &data);
2930 if (status < 0)
2931 goto error;
2932 if (data == 127)
2933 *count = *count + 1;
2934 status = read16(state, IQM_AF_PHASE2__A, &data);
2935 if (status < 0)
2936 goto error;
2937 if (data == 127)
2938 *count = *count + 1;
2939
2940error:
2941 if (status < 0)
2942 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002943 return status;
2944}
2945
2946static int ADCSynchronization(struct drxk_state *state)
2947{
2948 u16 count = 0;
2949 int status;
2950
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002951 dprintk(1, "\n");
2952
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002953 status = ADCSyncMeasurement(state, &count);
2954 if (status < 0)
2955 goto error;
2956
2957 if (count == 1) {
2958 /* Try sampling on a diffrent edge */
2959 u16 clkNeg = 0;
2960
2961 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2962 if (status < 0)
2963 goto error;
2964 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2965 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2966 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2967 clkNeg |=
2968 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2969 } else {
2970 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2971 clkNeg |=
2972 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2973 }
2974 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2975 if (status < 0)
2976 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002977 status = ADCSyncMeasurement(state, &count);
2978 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002979 goto error;
2980 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002981
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002982 if (count < 2)
2983 status = -EINVAL;
2984error:
2985 if (status < 0)
2986 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002987 return status;
2988}
2989
2990static int SetFrequencyShifter(struct drxk_state *state,
2991 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002992 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002993{
2994 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002995 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002996 u32 fmFrequencyShift = 0;
2997 bool tunerMirror = !state->m_bMirrorFreqSpect;
2998 u32 adcFreq;
2999 bool adcFlip;
3000 int status;
3001 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003002 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003003 u32 frequencyShift;
3004 bool imageToSelect;
3005
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003006 dprintk(1, "\n");
3007
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003008 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003009 Program frequency shifter
3010 No need to account for mirroring on RF
3011 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003012 if (isDTV) {
3013 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3014 (state->m_OperationMode == OM_QAM_ITU_C) ||
3015 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003016 selectPosImage = true;
3017 else
3018 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003019 }
3020 if (tunerMirror)
3021 /* tuner doesn't mirror */
3022 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003023 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003024 else
3025 /* tuner mirrors */
3026 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003027 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003028 if (ifFreqActual > samplingFrequency / 2) {
3029 /* adc mirrors */
3030 adcFreq = samplingFrequency - ifFreqActual;
3031 adcFlip = true;
3032 } else {
3033 /* adc doesn't mirror */
3034 adcFreq = ifFreqActual;
3035 adcFlip = false;
3036 }
3037
3038 frequencyShift = adcFreq;
3039 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003040 adcFlip ^ selectPosImage;
3041 state->m_IqmFsRateOfs =
3042 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003043
3044 if (imageToSelect)
3045 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3046
3047 /* Program frequency shifter with tuner offset compensation */
3048 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003049 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3050 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003051 if (status < 0)
3052 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003053 return status;
3054}
3055
3056static int InitAGC(struct drxk_state *state, bool isDTV)
3057{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003058 u16 ingainTgt = 0;
3059 u16 ingainTgtMin = 0;
3060 u16 ingainTgtMax = 0;
3061 u16 clpCyclen = 0;
3062 u16 clpSumMin = 0;
3063 u16 clpDirTo = 0;
3064 u16 snsSumMin = 0;
3065 u16 snsSumMax = 0;
3066 u16 clpSumMax = 0;
3067 u16 snsDirTo = 0;
3068 u16 kiInnergainMin = 0;
3069 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003070 u16 ifIaccuHiTgtMin = 0;
3071 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003072 u16 data = 0;
3073 u16 fastClpCtrlDelay = 0;
3074 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003075 int status = 0;
3076
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003077 dprintk(1, "\n");
3078
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003079 /* Common settings */
3080 snsSumMax = 1023;
3081 ifIaccuHiTgtMin = 2047;
3082 clpCyclen = 500;
3083 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003084
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003085 if (IsQAM(state)) {
3086 /* Standard specific settings */
3087 clpSumMin = 8;
3088 clpDirTo = (u16) -9;
3089 clpCtrlMode = 0;
3090 snsSumMin = 8;
3091 snsDirTo = (u16) -9;
3092 kiInnergainMin = (u16) -1030;
3093 } else {
3094 status = -EINVAL;
3095 goto error;
3096 }
3097 if (IsQAM(state)) {
3098 ifIaccuHiTgtMax = 0x2380;
3099 ifIaccuHiTgt = 0x2380;
3100 ingainTgtMin = 0x0511;
3101 ingainTgt = 0x0511;
3102 ingainTgtMax = 5119;
3103 fastClpCtrlDelay =
3104 state->m_qamIfAgcCfg.FastClipCtrlDelay;
3105 } else {
3106 ifIaccuHiTgtMax = 0x1200;
3107 ifIaccuHiTgt = 0x1200;
3108 ingainTgtMin = 13424;
3109 ingainTgt = 13424;
3110 ingainTgtMax = 30000;
3111 fastClpCtrlDelay =
3112 state->m_dvbtIfAgcCfg.FastClipCtrlDelay;
3113 }
3114 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3115 if (status < 0)
3116 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003117
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003118 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3119 if (status < 0)
3120 goto error;
3121 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3122 if (status < 0)
3123 goto error;
3124 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3125 if (status < 0)
3126 goto error;
3127 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3128 if (status < 0)
3129 goto error;
3130 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3131 if (status < 0)
3132 goto error;
3133 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3134 if (status < 0)
3135 goto error;
3136 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3137 if (status < 0)
3138 goto error;
3139 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3140 if (status < 0)
3141 goto error;
3142 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3143 if (status < 0)
3144 goto error;
3145 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3146 if (status < 0)
3147 goto error;
3148 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3149 if (status < 0)
3150 goto error;
3151 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3152 if (status < 0)
3153 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003154
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003155 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3156 if (status < 0)
3157 goto error;
3158 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3159 if (status < 0)
3160 goto error;
3161 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3162 if (status < 0)
3163 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003164
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003165 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3166 if (status < 0)
3167 goto error;
3168 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3169 if (status < 0)
3170 goto error;
3171 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3172 if (status < 0)
3173 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003174
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003175 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3176 if (status < 0)
3177 goto error;
3178 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3179 if (status < 0)
3180 goto error;
3181 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3182 if (status < 0)
3183 goto error;
3184 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3185 if (status < 0)
3186 goto error;
3187 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3188 if (status < 0)
3189 goto error;
3190 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3191 if (status < 0)
3192 goto error;
3193 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3194 if (status < 0)
3195 goto error;
3196 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3197 if (status < 0)
3198 goto error;
3199 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3200 if (status < 0)
3201 goto error;
3202 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3203 if (status < 0)
3204 goto error;
3205 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3206 if (status < 0)
3207 goto error;
3208 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3209 if (status < 0)
3210 goto error;
3211 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3212 if (status < 0)
3213 goto error;
3214 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3215 if (status < 0)
3216 goto error;
3217 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3218 if (status < 0)
3219 goto error;
3220 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3221 if (status < 0)
3222 goto error;
3223 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3224 if (status < 0)
3225 goto error;
3226 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3227 if (status < 0)
3228 goto error;
3229 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3230 if (status < 0)
3231 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003232
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003233 /* Initialize inner-loop KI gain factors */
3234 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3235 if (status < 0)
3236 goto error;
3237 if (IsQAM(state)) {
3238 data = 0x0657;
3239 data &= ~SCU_RAM_AGC_KI_RF__M;
3240 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3241 data &= ~SCU_RAM_AGC_KI_IF__M;
3242 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3243 }
3244 status = write16(state, SCU_RAM_AGC_KI__A, data);
3245error:
3246 if (status < 0)
3247 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003248 return status;
3249}
3250
Oliver Endrissebc7de22011-07-03 13:49:44 -03003251static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003252{
3253 int status;
3254
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003255 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003256 if (packetErr == NULL)
3257 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3258 else
3259 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3260 if (status < 0)
3261 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003262 return status;
3263}
3264
3265static int DVBTScCommand(struct drxk_state *state,
3266 u16 cmd, u16 subcmd,
3267 u16 param0, u16 param1, u16 param2,
3268 u16 param3, u16 param4)
3269{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003270 u16 curCmd = 0;
3271 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003272 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003273 u16 scExec = 0;
3274 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003275
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003276 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003277 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003278 if (scExec != 1) {
3279 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003280 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003281 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003282 if (status < 0)
3283 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003284
3285 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003286 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003287 do {
3288 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003289 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003290 retryCnt++;
3291 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003292 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3293 goto error;
3294
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003295 /* Write sub-command */
3296 switch (cmd) {
3297 /* All commands using sub-cmd */
3298 case OFDM_SC_RA_RAM_CMD_PROC_START:
3299 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3300 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003301 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3302 if (status < 0)
3303 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003304 break;
3305 default:
3306 /* Do nothing */
3307 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003308 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003309
3310 /* Write needed parameters and the command */
3311 switch (cmd) {
3312 /* All commands using 5 parameters */
3313 /* All commands using 4 parameters */
3314 /* All commands using 3 parameters */
3315 /* All commands using 2 parameters */
3316 case OFDM_SC_RA_RAM_CMD_PROC_START:
3317 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3318 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003319 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003320 /* All commands using 1 parameters */
3321 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3322 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003323 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003324 /* All commands using 0 parameters */
3325 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3326 case OFDM_SC_RA_RAM_CMD_NULL:
3327 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003328 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003329 break;
3330 default:
3331 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003332 status = -EINVAL;
3333 }
3334 if (status < 0)
3335 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003336
3337 /* Wait until sc is ready processing command */
3338 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003339 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003340 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003341 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003342 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003343 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003344 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3345 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003346
3347 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003348 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003349 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003350 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003351 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003352 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003353 if (status < 0)
3354 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003355
3356 /* Retreive results parameters from SC */
3357 switch (cmd) {
3358 /* All commands yielding 5 results */
3359 /* All commands yielding 4 results */
3360 /* All commands yielding 3 results */
3361 /* All commands yielding 2 results */
3362 /* All commands yielding 1 result */
3363 case OFDM_SC_RA_RAM_CMD_USER_IO:
3364 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003365 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003366 /* All commands yielding 0 results */
3367 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3368 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3369 case OFDM_SC_RA_RAM_CMD_PROC_START:
3370 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3371 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3372 case OFDM_SC_RA_RAM_CMD_NULL:
3373 break;
3374 default:
3375 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003376 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003377 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003378 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003379error:
3380 if (status < 0)
3381 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003382 return status;
3383}
3384
Oliver Endrissebc7de22011-07-03 13:49:44 -03003385static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003386{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003387 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003388 int status;
3389
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003390 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003391 status = CtrlPowerMode(state, &powerMode);
3392 if (status < 0)
3393 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003394 return status;
3395}
3396
Oliver Endrissebc7de22011-07-03 13:49:44 -03003397static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003398{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003399 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003400
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003401 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003402 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003403 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003404 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003405 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003406 if (status < 0)
3407 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003408 return status;
3409}
3410
3411#define DEFAULT_FR_THRES_8K 4000
3412static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3413{
3414
3415 int status;
3416
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003417 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003418 if (*enabled == true) {
3419 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003420 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003421 DEFAULT_FR_THRES_8K);
3422 } else {
3423 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003424 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003425 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003426 if (status < 0)
3427 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003428
3429 return status;
3430}
3431
3432static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3433 struct DRXKCfgDvbtEchoThres_t *echoThres)
3434{
3435 u16 data = 0;
3436 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003437
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003438 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003439 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3440 if (status < 0)
3441 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003442
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003443 switch (echoThres->fftMode) {
3444 case DRX_FFTMODE_2K:
3445 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3446 data |= ((echoThres->threshold <<
3447 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3448 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3449 goto error;
3450 case DRX_FFTMODE_8K:
3451 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3452 data |= ((echoThres->threshold <<
3453 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3454 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3455 goto error;
3456 default:
3457 return -EINVAL;
3458 goto error;
3459 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003460
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003461 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3462error:
3463 if (status < 0)
3464 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003465 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003466}
3467
3468static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003469 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003470{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003471 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003472
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003473 dprintk(1, "\n");
3474
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003475 switch (*speed) {
3476 case DRXK_DVBT_SQI_SPEED_FAST:
3477 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3478 case DRXK_DVBT_SQI_SPEED_SLOW:
3479 break;
3480 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003481 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003482 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003483 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003484 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003485error:
3486 if (status < 0)
3487 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003488 return status;
3489}
3490
3491/*============================================================================*/
3492
3493/**
3494* \brief Activate DVBT specific presets
3495* \param demod instance of demodulator.
3496* \return DRXStatus_t.
3497*
3498* Called in DVBTSetStandard
3499*
3500*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003501static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003502{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003503 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003504 bool setincenable = false;
3505 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003506
Oliver Endrissebc7de22011-07-03 13:49:44 -03003507 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3508 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003509
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003510 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003511 status = DVBTCtrlSetIncEnable(state, &setincenable);
3512 if (status < 0)
3513 goto error;
3514 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3515 if (status < 0)
3516 goto error;
3517 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3518 if (status < 0)
3519 goto error;
3520 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3521 if (status < 0)
3522 goto error;
3523 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3524error:
3525 if (status < 0)
3526 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003527 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003528}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003529
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003530/*============================================================================*/
3531
3532/**
3533* \brief Initialize channelswitch-independent settings for DVBT.
3534* \param demod instance of demodulator.
3535* \return DRXStatus_t.
3536*
3537* For ROM code channel filter taps are loaded from the bootloader. For microcode
3538* the DVB-T taps from the drxk_filters.h are used.
3539*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003540static int SetDVBTStandard(struct drxk_state *state,
3541 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003542{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003543 u16 cmdResult = 0;
3544 u16 data = 0;
3545 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003546
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003547 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003548
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003549 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003550 /* added antenna switch */
3551 SwitchAntennaToDVBT(state);
3552 /* send OFDM reset command */
3553 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003554 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003555 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003556
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003557 /* send OFDM setenv command */
3558 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3559 if (status < 0)
3560 goto error;
3561
3562 /* reset datapath for OFDM, processors first */
3563 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3564 if (status < 0)
3565 goto error;
3566 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3567 if (status < 0)
3568 goto error;
3569 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3570 if (status < 0)
3571 goto error;
3572
3573 /* IQM setup */
3574 /* synchronize on ofdstate->m_festart */
3575 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3576 if (status < 0)
3577 goto error;
3578 /* window size for clipping ADC detection */
3579 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3580 if (status < 0)
3581 goto error;
3582 /* window size for for sense pre-SAW detection */
3583 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3584 if (status < 0)
3585 goto error;
3586 /* sense threshold for sense pre-SAW detection */
3587 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3588 if (status < 0)
3589 goto error;
3590 status = SetIqmAf(state, true);
3591 if (status < 0)
3592 goto error;
3593
3594 status = write16(state, IQM_AF_AGC_RF__A, 0);
3595 if (status < 0)
3596 goto error;
3597
3598 /* Impulse noise cruncher setup */
3599 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3600 if (status < 0)
3601 goto error;
3602 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3603 if (status < 0)
3604 goto error;
3605 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3606 if (status < 0)
3607 goto error;
3608
3609 status = write16(state, IQM_RC_STRETCH__A, 16);
3610 if (status < 0)
3611 goto error;
3612 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3613 if (status < 0)
3614 goto error;
3615 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3616 if (status < 0)
3617 goto error;
3618 status = write16(state, IQM_CF_SCALE__A, 1600);
3619 if (status < 0)
3620 goto error;
3621 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3622 if (status < 0)
3623 goto error;
3624
3625 /* virtual clipping threshold for clipping ADC detection */
3626 status = write16(state, IQM_AF_CLP_TH__A, 448);
3627 if (status < 0)
3628 goto error;
3629 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3630 if (status < 0)
3631 goto error;
3632
3633 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3634 if (status < 0)
3635 goto error;
3636
3637 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3638 if (status < 0)
3639 goto error;
3640 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3641 if (status < 0)
3642 goto error;
3643 /* enable power measurement interrupt */
3644 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3645 if (status < 0)
3646 goto error;
3647 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3648 if (status < 0)
3649 goto error;
3650
3651 /* IQM will not be reset from here, sync ADC and update/init AGC */
3652 status = ADCSynchronization(state);
3653 if (status < 0)
3654 goto error;
3655 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3656 if (status < 0)
3657 goto error;
3658
3659 /* Halt SCU to enable safe non-atomic accesses */
3660 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3661 if (status < 0)
3662 goto error;
3663
3664 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3665 if (status < 0)
3666 goto error;
3667 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3668 if (status < 0)
3669 goto error;
3670
3671 /* Set Noise Estimation notch width and enable DC fix */
3672 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3673 if (status < 0)
3674 goto error;
3675 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3676 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3677 if (status < 0)
3678 goto error;
3679
3680 /* Activate SCU to enable SCU commands */
3681 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3682 if (status < 0)
3683 goto error;
3684
3685 if (!state->m_DRXK_A3_ROM_CODE) {
3686 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3687 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3688 if (status < 0)
3689 goto error;
3690 }
3691
3692 /* OFDM_SC setup */
3693#ifdef COMPILE_FOR_NONRT
3694 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3695 if (status < 0)
3696 goto error;
3697 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3698 if (status < 0)
3699 goto error;
3700#endif
3701
3702 /* FEC setup */
3703 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3704 if (status < 0)
3705 goto error;
3706
3707
3708#ifdef COMPILE_FOR_NONRT
3709 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3710 if (status < 0)
3711 goto error;
3712#else
3713 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3714 if (status < 0)
3715 goto error;
3716#endif
3717 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3718 if (status < 0)
3719 goto error;
3720
3721 /* Setup MPEG bus */
3722 status = MPEGTSDtoSetup(state, OM_DVBT);
3723 if (status < 0)
3724 goto error;
3725 /* Set DVBT Presets */
3726 status = DVBTActivatePresets(state);
3727 if (status < 0)
3728 goto error;
3729
3730error:
3731 if (status < 0)
3732 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003733 return status;
3734}
3735
3736/*============================================================================*/
3737/**
3738* \brief Start dvbt demodulating for channel.
3739* \param demod instance of demodulator.
3740* \return DRXStatus_t.
3741*/
3742static int DVBTStart(struct drxk_state *state)
3743{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003744 u16 param1;
3745 int status;
3746 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003747
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003748 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003749 /* Start correct processes to get in lock */
3750 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003751 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3752 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3753 if (status < 0)
3754 goto error;
3755 /* Start FEC OC */
3756 status = MPEGTSStart(state);
3757 if (status < 0)
3758 goto error;
3759 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3760 if (status < 0)
3761 goto error;
3762error:
3763 if (status < 0)
3764 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003765 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003766}
3767
3768
3769/*============================================================================*/
3770
3771/**
3772* \brief Set up dvbt demodulator for channel.
3773* \param demod instance of demodulator.
3774* \return DRXStatus_t.
3775* // original DVBTSetChannel()
3776*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003777static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3778 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003779{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003780 u16 cmdResult = 0;
3781 u16 transmissionParams = 0;
3782 u16 operationMode = 0;
3783 u32 iqmRcRateOfs = 0;
3784 u32 bandwidth = 0;
3785 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003786 int status;
3787
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003788 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003789
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003790 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3791 if (status < 0)
3792 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003793
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003794 /* Halt SCU to enable safe non-atomic accesses */
3795 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3796 if (status < 0)
3797 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003798
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003799 /* Stop processors */
3800 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3801 if (status < 0)
3802 goto error;
3803 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3804 if (status < 0)
3805 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003806
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003807 /* Mandatory fix, always stop CP, required to set spl offset back to
3808 hardware default (is set to 0 by ucode during pilot detection */
3809 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3810 if (status < 0)
3811 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003812
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003813 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003814
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003815 /* mode */
3816 switch (state->param.u.ofdm.transmission_mode) {
3817 case TRANSMISSION_MODE_AUTO:
3818 default:
3819 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3820 /* fall through , try first guess DRX_FFTMODE_8K */
3821 case TRANSMISSION_MODE_8K:
3822 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
3823 goto error;
3824 case TRANSMISSION_MODE_2K:
3825 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
3826 goto error;
3827 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003828
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003829 /* guard */
3830 switch (state->param.u.ofdm.guard_interval) {
3831 default:
3832 case GUARD_INTERVAL_AUTO:
3833 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3834 /* fall through , try first guess DRX_GUARD_1DIV4 */
3835 case GUARD_INTERVAL_1_4:
3836 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
3837 goto error;
3838 case GUARD_INTERVAL_1_32:
3839 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
3840 goto error;
3841 case GUARD_INTERVAL_1_16:
3842 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
3843 goto error;
3844 case GUARD_INTERVAL_1_8:
3845 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
3846 goto error;
3847 }
3848
3849 /* hierarchy */
3850 switch (state->param.u.ofdm.hierarchy_information) {
3851 case HIERARCHY_AUTO:
3852 case HIERARCHY_NONE:
3853 default:
3854 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3855 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3856 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3857 /* break; */
3858 case HIERARCHY_1:
3859 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3860 break;
3861 case HIERARCHY_2:
3862 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3863 break;
3864 case HIERARCHY_4:
3865 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3866 break;
3867 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003868
3869
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003870 /* constellation */
3871 switch (state->param.u.ofdm.constellation) {
3872 case QAM_AUTO:
3873 default:
3874 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3875 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3876 case QAM_64:
3877 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3878 break;
3879 case QPSK:
3880 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3881 break;
3882 case QAM_16:
3883 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3884 break;
3885 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003886#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003887 /* No hierachical channels support in BDA */
3888 /* Priority (only for hierarchical channels) */
3889 switch (channel->priority) {
3890 case DRX_PRIORITY_LOW:
3891 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3892 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3893 OFDM_EC_SB_PRIOR_LO);
3894 break;
3895 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003896 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003897 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3898 OFDM_EC_SB_PRIOR_HI));
3899 break;
3900 case DRX_PRIORITY_UNKNOWN: /* fall through */
3901 default:
3902 status = -EINVAL;
3903 goto error;
3904 }
3905#else
3906 /* Set Priorty high */
3907 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3908 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3909 if (status < 0)
3910 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003911#endif
3912
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003913 /* coderate */
3914 switch (state->param.u.ofdm.code_rate_HP) {
3915 case FEC_AUTO:
3916 default:
3917 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3918 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3919 case FEC_2_3:
3920 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3921 break;
3922 case FEC_1_2:
3923 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3924 break;
3925 case FEC_3_4:
3926 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3927 break;
3928 case FEC_5_6:
3929 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3930 break;
3931 case FEC_7_8:
3932 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3933 break;
3934 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003935
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003936 /* SAW filter selection: normaly not necesarry, but if wanted
3937 the application can select a SAW filter via the driver by using UIOs */
3938 /* First determine real bandwidth (Hz) */
3939 /* Also set delay for impulse noise cruncher */
3940 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3941 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3942 functions */
3943 switch (state->param.u.ofdm.bandwidth) {
3944 case BANDWIDTH_AUTO:
3945 case BANDWIDTH_8_MHZ:
3946 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3947 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003948 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003949 goto error;
3950 /* cochannel protection for PAL 8 MHz */
3951 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3952 if (status < 0)
3953 goto error;
3954 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3955 if (status < 0)
3956 goto error;
3957 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3958 if (status < 0)
3959 goto error;
3960 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3961 if (status < 0)
3962 goto error;
3963 break;
3964 case BANDWIDTH_7_MHZ:
3965 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3966 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3967 if (status < 0)
3968 goto error;
3969 /* cochannel protection for PAL 7 MHz */
3970 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3971 if (status < 0)
3972 goto error;
3973 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3974 if (status < 0)
3975 goto error;
3976 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3977 if (status < 0)
3978 goto error;
3979 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3980 if (status < 0)
3981 goto error;
3982 break;
3983 case BANDWIDTH_6_MHZ:
3984 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3985 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3986 if (status < 0)
3987 goto error;
3988 /* cochannel protection for NTSC 6 MHz */
3989 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3990 if (status < 0)
3991 goto error;
3992 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3993 if (status < 0)
3994 goto error;
3995 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3996 if (status < 0)
3997 goto error;
3998 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3999 if (status < 0)
4000 goto error;
4001 break;
4002 default:
4003 status = -EINVAL;
4004 goto error;
4005 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004006
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004007 if (iqmRcRateOfs == 0) {
4008 /* Now compute IQM_RC_RATE_OFS
4009 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4010 =>
4011 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4012 */
4013 /* (SysFreq / BandWidth) * (2^28) */
4014 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4015 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4016 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4017 iqmRcRateOfs = Frac28a((u32)
4018 ((state->m_sysClockFreq *
4019 1000) / 3), bandwidth);
4020 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4021 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4022 iqmRcRateOfs += 0x80L;
4023 iqmRcRateOfs = iqmRcRateOfs >> 7;
4024 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4025 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4026 }
4027
4028 iqmRcRateOfs &=
4029 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4030 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4031 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4032 if (status < 0)
4033 goto error;
4034
4035 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004036
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004037#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004038 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4039 if (status < 0)
4040 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004041#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004042 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4043 if (status < 0)
4044 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004045
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004046 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004047
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004048 /* Activate SCU to enable SCU commands */
4049 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4050 if (status < 0)
4051 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004052
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004053 /* Enable SC after setting all other parameters */
4054 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4055 if (status < 0)
4056 goto error;
4057 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4058 if (status < 0)
4059 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004060
4061
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004062 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4063 if (status < 0)
4064 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004065
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004066 /* Write SC parameter registers, set all AUTO flags in operation mode */
4067 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4068 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4069 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4070 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4071 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4072 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4073 0, transmissionParams, param1, 0, 0, 0);
4074 if (status < 0)
4075 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004076
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004077 if (!state->m_DRXK_A3_ROM_CODE)
4078 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4079error:
4080 if (status < 0)
4081 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004082
4083 return status;
4084}
4085
4086
4087/*============================================================================*/
4088
4089/**
4090* \brief Retreive lock status .
4091* \param demod Pointer to demodulator instance.
4092* \param lockStat Pointer to lock status structure.
4093* \return DRXStatus_t.
4094*
4095*/
4096static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4097{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004098 int status;
4099 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4100 OFDM_SC_RA_RAM_LOCK_FEC__M);
4101 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4102 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004103
Oliver Endrissebc7de22011-07-03 13:49:44 -03004104 u16 ScRaRamLock = 0;
4105 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004106
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004107 dprintk(1, "\n");
4108
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004109 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004110 /* driver 0.9.0 */
4111 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004112 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004113 if (status < 0)
4114 goto end;
4115 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4116 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004117
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004118 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004119 if (status < 0)
4120 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004121
Oliver Endrissebc7de22011-07-03 13:49:44 -03004122 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4123 *pLockStatus = MPEG_LOCK;
4124 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4125 *pLockStatus = FEC_LOCK;
4126 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4127 *pLockStatus = DEMOD_LOCK;
4128 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4129 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004130end:
4131 if (status < 0)
4132 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004133
Oliver Endrissebc7de22011-07-03 13:49:44 -03004134 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004135}
4136
Oliver Endrissebc7de22011-07-03 13:49:44 -03004137static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004138{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004139 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004140 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004141
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004142 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004143 status = CtrlPowerMode(state, &powerMode);
4144 if (status < 0)
4145 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004146
Oliver Endrissebc7de22011-07-03 13:49:44 -03004147 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004148}
4149
4150
Oliver Endrissebc7de22011-07-03 13:49:44 -03004151/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004152static int PowerDownQAM(struct drxk_state *state)
4153{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004154 u16 data = 0;
4155 u16 cmdResult;
4156 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004157
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004158 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004159 status = read16(state, SCU_COMM_EXEC__A, &data);
4160 if (status < 0)
4161 goto error;
4162 if (data == SCU_COMM_EXEC_ACTIVE) {
4163 /*
4164 STOP demodulator
4165 QAM and HW blocks
4166 */
4167 /* stop all comstate->m_exec */
4168 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004169 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004170 goto error;
4171 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004172 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004173 goto error;
4174 }
4175 /* powerdown AFE */
4176 status = SetIqmAf(state, false);
4177
4178error:
4179 if (status < 0)
4180 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004181
Oliver Endrissebc7de22011-07-03 13:49:44 -03004182 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004183}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004184
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004185/*============================================================================*/
4186
4187/**
4188* \brief Setup of the QAM Measurement intervals for signal quality
4189* \param demod instance of demod.
4190* \param constellation current constellation.
4191* \return DRXStatus_t.
4192*
4193* NOTE:
4194* Take into account that for certain settings the errorcounters can overflow.
4195* The implementation does not check this.
4196*
4197*/
4198static int SetQAMMeasurement(struct drxk_state *state,
4199 enum EDrxkConstellation constellation,
4200 u32 symbolRate)
4201{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004202 u32 fecBitsDesired = 0; /* BER accounting period */
4203 u32 fecRsPeriodTotal = 0; /* Total period */
4204 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4205 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004206 int status = 0;
4207
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004208 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004209
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004210 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004211 /* fecBitsDesired = symbolRate [kHz] *
4212 FrameLenght [ms] *
4213 (constellation + 1) *
4214 SyncLoss (== 1) *
4215 ViterbiLoss (==1)
4216 */
4217 switch (constellation) {
4218 case DRX_CONSTELLATION_QAM16:
4219 fecBitsDesired = 4 * symbolRate;
4220 break;
4221 case DRX_CONSTELLATION_QAM32:
4222 fecBitsDesired = 5 * symbolRate;
4223 break;
4224 case DRX_CONSTELLATION_QAM64:
4225 fecBitsDesired = 6 * symbolRate;
4226 break;
4227 case DRX_CONSTELLATION_QAM128:
4228 fecBitsDesired = 7 * symbolRate;
4229 break;
4230 case DRX_CONSTELLATION_QAM256:
4231 fecBitsDesired = 8 * symbolRate;
4232 break;
4233 default:
4234 status = -EINVAL;
4235 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004236 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004237 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004238
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004239 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4240 fecBitsDesired *= 500; /* meas. period [ms] */
4241
4242 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4243 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4244 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4245
4246 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4247 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4248 if (fecRsPrescale == 0) {
4249 /* Divide by zero (though impossible) */
4250 status = -EINVAL;
4251 if (status < 0)
4252 goto error;
4253 }
4254 fecRsPeriod =
4255 ((u16) fecRsPeriodTotal +
4256 (fecRsPrescale >> 1)) / fecRsPrescale;
4257
4258 /* write corresponding registers */
4259 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4260 if (status < 0)
4261 goto error;
4262 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4263 if (status < 0)
4264 goto error;
4265 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4266error:
4267 if (status < 0)
4268 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004269 return status;
4270}
4271
Oliver Endrissebc7de22011-07-03 13:49:44 -03004272static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004273{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004274 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004275
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004276 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004277 /* QAM Equalizer Setup */
4278 /* Equalizer */
4279 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4280 if (status < 0)
4281 goto error;
4282 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4283 if (status < 0)
4284 goto error;
4285 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4286 if (status < 0)
4287 goto error;
4288 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4289 if (status < 0)
4290 goto error;
4291 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4292 if (status < 0)
4293 goto error;
4294 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4295 if (status < 0)
4296 goto error;
4297 /* Decision Feedback Equalizer */
4298 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4299 if (status < 0)
4300 goto error;
4301 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4302 if (status < 0)
4303 goto error;
4304 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4305 if (status < 0)
4306 goto error;
4307 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4308 if (status < 0)
4309 goto error;
4310 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4311 if (status < 0)
4312 goto error;
4313 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4314 if (status < 0)
4315 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004316
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004317 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4318 if (status < 0)
4319 goto error;
4320 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4321 if (status < 0)
4322 goto error;
4323 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4324 if (status < 0)
4325 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004326
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004327 /* QAM Slicer Settings */
4328 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4329 if (status < 0)
4330 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004331
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004332 /* QAM Loop Controller Coeficients */
4333 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4334 if (status < 0)
4335 goto error;
4336 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4337 if (status < 0)
4338 goto error;
4339 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4340 if (status < 0)
4341 goto error;
4342 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4343 if (status < 0)
4344 goto error;
4345 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4346 if (status < 0)
4347 goto error;
4348 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4349 if (status < 0)
4350 goto error;
4351 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4352 if (status < 0)
4353 goto error;
4354 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4355 if (status < 0)
4356 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004357
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004358 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4359 if (status < 0)
4360 goto error;
4361 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4362 if (status < 0)
4363 goto error;
4364 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4365 if (status < 0)
4366 goto error;
4367 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4368 if (status < 0)
4369 goto error;
4370 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4371 if (status < 0)
4372 goto error;
4373 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4374 if (status < 0)
4375 goto error;
4376 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4377 if (status < 0)
4378 goto error;
4379 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4380 if (status < 0)
4381 goto error;
4382 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4383 if (status < 0)
4384 goto error;
4385 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4386 if (status < 0)
4387 goto error;
4388 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4389 if (status < 0)
4390 goto error;
4391 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4392 if (status < 0)
4393 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004394
4395
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004396 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004397
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004398 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4399 if (status < 0)
4400 goto error;
4401 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4402 if (status < 0)
4403 goto error;
4404 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4405 if (status < 0)
4406 goto error;
4407 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4408 if (status < 0)
4409 goto error;
4410 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4411 if (status < 0)
4412 goto error;
4413 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4414 if (status < 0)
4415 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004416
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004417 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4418 if (status < 0)
4419 goto error;
4420 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4421 if (status < 0)
4422 goto error;
4423 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4424 if (status < 0)
4425 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004426
4427
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004428 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004429
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004430 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4431 if (status < 0)
4432 goto error;
4433 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4434 if (status < 0)
4435 goto error;
4436 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4437 if (status < 0)
4438 goto error;
4439 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4440 if (status < 0)
4441 goto error;
4442 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4443 if (status < 0)
4444 goto error;
4445 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4446 if (status < 0)
4447 goto error;
4448 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4449 if (status < 0)
4450 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004451
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004452error:
4453 if (status < 0)
4454 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004455 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004456}
4457
4458/*============================================================================*/
4459
4460/**
4461* \brief QAM32 specific setup
4462* \param demod instance of demod.
4463* \return DRXStatus_t.
4464*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004465static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004466{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004467 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004468
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004469 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004470
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004471 /* QAM Equalizer Setup */
4472 /* Equalizer */
4473 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4474 if (status < 0)
4475 goto error;
4476 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4477 if (status < 0)
4478 goto error;
4479 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4480 if (status < 0)
4481 goto error;
4482 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4483 if (status < 0)
4484 goto error;
4485 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4486 if (status < 0)
4487 goto error;
4488 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4489 if (status < 0)
4490 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004491
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004492 /* Decision Feedback Equalizer */
4493 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4494 if (status < 0)
4495 goto error;
4496 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4497 if (status < 0)
4498 goto error;
4499 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4500 if (status < 0)
4501 goto error;
4502 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4503 if (status < 0)
4504 goto error;
4505 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4506 if (status < 0)
4507 goto error;
4508 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4509 if (status < 0)
4510 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004511
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004512 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4513 if (status < 0)
4514 goto error;
4515 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4516 if (status < 0)
4517 goto error;
4518 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4519 if (status < 0)
4520 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004521
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004522 /* QAM Slicer Settings */
4523
4524 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4525 if (status < 0)
4526 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004527
4528
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004529 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004530
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004531 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4532 if (status < 0)
4533 goto error;
4534 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4535 if (status < 0)
4536 goto error;
4537 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4538 if (status < 0)
4539 goto error;
4540 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4541 if (status < 0)
4542 goto error;
4543 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4544 if (status < 0)
4545 goto error;
4546 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4547 if (status < 0)
4548 goto error;
4549 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4550 if (status < 0)
4551 goto error;
4552 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4553 if (status < 0)
4554 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004555
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004556 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4557 if (status < 0)
4558 goto error;
4559 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4560 if (status < 0)
4561 goto error;
4562 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4563 if (status < 0)
4564 goto error;
4565 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4566 if (status < 0)
4567 goto error;
4568 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4569 if (status < 0)
4570 goto error;
4571 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4572 if (status < 0)
4573 goto error;
4574 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4575 if (status < 0)
4576 goto error;
4577 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4578 if (status < 0)
4579 goto error;
4580 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4581 if (status < 0)
4582 goto error;
4583 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4584 if (status < 0)
4585 goto error;
4586 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4587 if (status < 0)
4588 goto error;
4589 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4590 if (status < 0)
4591 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004592
4593
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004594 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004595
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004596 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4597 if (status < 0)
4598 goto error;
4599 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4600 if (status < 0)
4601 goto error;
4602 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4603 if (status < 0)
4604 goto error;
4605 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4606 if (status < 0)
4607 goto error;
4608 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4609 if (status < 0)
4610 goto error;
4611 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4612 if (status < 0)
4613 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004614
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004615 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4616 if (status < 0)
4617 goto error;
4618 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4619 if (status < 0)
4620 goto error;
4621 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4622 if (status < 0)
4623 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004624
4625
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004626 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004627
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004628 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4629 if (status < 0)
4630 goto error;
4631 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4632 if (status < 0)
4633 goto error;
4634 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4635 if (status < 0)
4636 goto error;
4637 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4638 if (status < 0)
4639 goto error;
4640 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4641 if (status < 0)
4642 goto error;
4643 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4644 if (status < 0)
4645 goto error;
4646 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4647error:
4648 if (status < 0)
4649 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004650 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004651}
4652
4653/*============================================================================*/
4654
4655/**
4656* \brief QAM64 specific setup
4657* \param demod instance of demod.
4658* \return DRXStatus_t.
4659*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004660static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004661{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004662 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004663
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004664 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004665 /* QAM Equalizer Setup */
4666 /* Equalizer */
4667 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4668 if (status < 0)
4669 goto error;
4670 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4671 if (status < 0)
4672 goto error;
4673 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4674 if (status < 0)
4675 goto error;
4676 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4677 if (status < 0)
4678 goto error;
4679 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4680 if (status < 0)
4681 goto error;
4682 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4683 if (status < 0)
4684 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004685
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004686 /* Decision Feedback Equalizer */
4687 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4688 if (status < 0)
4689 goto error;
4690 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4691 if (status < 0)
4692 goto error;
4693 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4694 if (status < 0)
4695 goto error;
4696 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4697 if (status < 0)
4698 goto error;
4699 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4700 if (status < 0)
4701 goto error;
4702 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4703 if (status < 0)
4704 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004705
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004706 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4707 if (status < 0)
4708 goto error;
4709 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4710 if (status < 0)
4711 goto error;
4712 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4713 if (status < 0)
4714 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004715
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004716 /* QAM Slicer Settings */
4717 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4718 if (status < 0)
4719 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004720
4721
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004722 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004723
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004724 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4725 if (status < 0)
4726 goto error;
4727 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4728 if (status < 0)
4729 goto error;
4730 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4731 if (status < 0)
4732 goto error;
4733 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4734 if (status < 0)
4735 goto error;
4736 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4737 if (status < 0)
4738 goto error;
4739 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4740 if (status < 0)
4741 goto error;
4742 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4743 if (status < 0)
4744 goto error;
4745 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4746 if (status < 0)
4747 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004748
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004749 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4750 if (status < 0)
4751 goto error;
4752 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4753 if (status < 0)
4754 goto error;
4755 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4756 if (status < 0)
4757 goto error;
4758 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4759 if (status < 0)
4760 goto error;
4761 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4762 if (status < 0)
4763 goto error;
4764 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4765 if (status < 0)
4766 goto error;
4767 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4768 if (status < 0)
4769 goto error;
4770 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4771 if (status < 0)
4772 goto error;
4773 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4774 if (status < 0)
4775 goto error;
4776 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4777 if (status < 0)
4778 goto error;
4779 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4780 if (status < 0)
4781 goto error;
4782 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4783 if (status < 0)
4784 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004785
4786
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004787 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004788
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004789 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4790 if (status < 0)
4791 goto error;
4792 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4793 if (status < 0)
4794 goto error;
4795 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4796 if (status < 0)
4797 goto error;
4798 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4799 if (status < 0)
4800 goto error;
4801 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4802 if (status < 0)
4803 goto error;
4804 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4805 if (status < 0)
4806 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004807
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004808 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4809 if (status < 0)
4810 goto error;
4811 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4812 if (status < 0)
4813 goto error;
4814 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4815 if (status < 0)
4816 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004817
4818
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004819 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004820
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004821 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4822 if (status < 0)
4823 goto error;
4824 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4825 if (status < 0)
4826 goto error;
4827 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4828 if (status < 0)
4829 goto error;
4830 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4831 if (status < 0)
4832 goto error;
4833 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4834 if (status < 0)
4835 goto error;
4836 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4837 if (status < 0)
4838 goto error;
4839 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4840error:
4841 if (status < 0)
4842 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004843
Oliver Endrissebc7de22011-07-03 13:49:44 -03004844 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004845}
4846
4847/*============================================================================*/
4848
4849/**
4850* \brief QAM128 specific setup
4851* \param demod: instance of demod.
4852* \return DRXStatus_t.
4853*/
4854static int SetQAM128(struct drxk_state *state)
4855{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004856 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004857
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004858 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004859 /* QAM Equalizer Setup */
4860 /* Equalizer */
4861 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4862 if (status < 0)
4863 goto error;
4864 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4865 if (status < 0)
4866 goto error;
4867 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4868 if (status < 0)
4869 goto error;
4870 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4871 if (status < 0)
4872 goto error;
4873 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4874 if (status < 0)
4875 goto error;
4876 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4877 if (status < 0)
4878 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004879
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004880 /* Decision Feedback Equalizer */
4881 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4882 if (status < 0)
4883 goto error;
4884 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4885 if (status < 0)
4886 goto error;
4887 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4888 if (status < 0)
4889 goto error;
4890 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4891 if (status < 0)
4892 goto error;
4893 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4894 if (status < 0)
4895 goto error;
4896 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4897 if (status < 0)
4898 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004899
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004900 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4901 if (status < 0)
4902 goto error;
4903 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4904 if (status < 0)
4905 goto error;
4906 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4907 if (status < 0)
4908 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004909
4910
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004911 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004912
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004913 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4914 if (status < 0)
4915 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004916
4917
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004918 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004919
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004920 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4921 if (status < 0)
4922 goto error;
4923 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4924 if (status < 0)
4925 goto error;
4926 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4927 if (status < 0)
4928 goto error;
4929 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4930 if (status < 0)
4931 goto error;
4932 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4933 if (status < 0)
4934 goto error;
4935 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4936 if (status < 0)
4937 goto error;
4938 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4939 if (status < 0)
4940 goto error;
4941 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4942 if (status < 0)
4943 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004944
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004945 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4946 if (status < 0)
4947 goto error;
4948 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4949 if (status < 0)
4950 goto error;
4951 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4952 if (status < 0)
4953 goto error;
4954 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4955 if (status < 0)
4956 goto error;
4957 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4958 if (status < 0)
4959 goto error;
4960 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4961 if (status < 0)
4962 goto error;
4963 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4964 if (status < 0)
4965 goto error;
4966 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4967 if (status < 0)
4968 goto error;
4969 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4970 if (status < 0)
4971 goto error;
4972 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4973 if (status < 0)
4974 goto error;
4975 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4976 if (status < 0)
4977 goto error;
4978 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4979 if (status < 0)
4980 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004981
4982
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004983 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004984
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004985 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4986 if (status < 0)
4987 goto error;
4988 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4989 if (status < 0)
4990 goto error;
4991 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4992 if (status < 0)
4993 goto error;
4994 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4995 if (status < 0)
4996 goto error;
4997 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4998 if (status < 0)
4999 goto error;
5000 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5001 if (status < 0)
5002 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005003
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005004 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5005 if (status < 0)
5006 goto error;
5007 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5008 if (status < 0)
5009 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005010
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005011 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5012 if (status < 0)
5013 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005014
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005015 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005016
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005017 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5018 if (status < 0)
5019 goto error;
5020 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5021 if (status < 0)
5022 goto error;
5023 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5024 if (status < 0)
5025 goto error;
5026 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5027 if (status < 0)
5028 goto error;
5029 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5030 if (status < 0)
5031 goto error;
5032 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5033 if (status < 0)
5034 goto error;
5035 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5036error:
5037 if (status < 0)
5038 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005039
Oliver Endrissebc7de22011-07-03 13:49:44 -03005040 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005041}
5042
5043/*============================================================================*/
5044
5045/**
5046* \brief QAM256 specific setup
5047* \param demod: instance of demod.
5048* \return DRXStatus_t.
5049*/
5050static int SetQAM256(struct drxk_state *state)
5051{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005052 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005053
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005054 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005055 /* QAM Equalizer Setup */
5056 /* Equalizer */
5057 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5058 if (status < 0)
5059 goto error;
5060 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5061 if (status < 0)
5062 goto error;
5063 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5064 if (status < 0)
5065 goto error;
5066 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5067 if (status < 0)
5068 goto error;
5069 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5070 if (status < 0)
5071 goto error;
5072 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5073 if (status < 0)
5074 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005076 /* Decision Feedback Equalizer */
5077 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5078 if (status < 0)
5079 goto error;
5080 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5081 if (status < 0)
5082 goto error;
5083 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5084 if (status < 0)
5085 goto error;
5086 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5087 if (status < 0)
5088 goto error;
5089 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5090 if (status < 0)
5091 goto error;
5092 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5093 if (status < 0)
5094 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005095
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005096 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5097 if (status < 0)
5098 goto error;
5099 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5100 if (status < 0)
5101 goto error;
5102 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5103 if (status < 0)
5104 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005105
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005106 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005107
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005108 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5109 if (status < 0)
5110 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005111
5112
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005113 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005114
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005115 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5116 if (status < 0)
5117 goto error;
5118 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5119 if (status < 0)
5120 goto error;
5121 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5122 if (status < 0)
5123 goto error;
5124 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5125 if (status < 0)
5126 goto error;
5127 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5128 if (status < 0)
5129 goto error;
5130 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5131 if (status < 0)
5132 goto error;
5133 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5134 if (status < 0)
5135 goto error;
5136 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5137 if (status < 0)
5138 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005139
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005140 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5141 if (status < 0)
5142 goto error;
5143 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5144 if (status < 0)
5145 goto error;
5146 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5147 if (status < 0)
5148 goto error;
5149 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5150 if (status < 0)
5151 goto error;
5152 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5153 if (status < 0)
5154 goto error;
5155 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5156 if (status < 0)
5157 goto error;
5158 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5159 if (status < 0)
5160 goto error;
5161 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5162 if (status < 0)
5163 goto error;
5164 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5165 if (status < 0)
5166 goto error;
5167 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5168 if (status < 0)
5169 goto error;
5170 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5171 if (status < 0)
5172 goto error;
5173 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5174 if (status < 0)
5175 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005176
5177
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005178 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005179
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005180 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5181 if (status < 0)
5182 goto error;
5183 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5184 if (status < 0)
5185 goto error;
5186 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5187 if (status < 0)
5188 goto error;
5189 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5190 if (status < 0)
5191 goto error;
5192 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5193 if (status < 0)
5194 goto error;
5195 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5196 if (status < 0)
5197 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005198
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005199 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5200 if (status < 0)
5201 goto error;
5202 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5203 if (status < 0)
5204 goto error;
5205 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5206 if (status < 0)
5207 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005208
5209
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005210 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005211
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005212 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5213 if (status < 0)
5214 goto error;
5215 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5216 if (status < 0)
5217 goto error;
5218 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5219 if (status < 0)
5220 goto error;
5221 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5222 if (status < 0)
5223 goto error;
5224 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5225 if (status < 0)
5226 goto error;
5227 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5228 if (status < 0)
5229 goto error;
5230 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5231error:
5232 if (status < 0)
5233 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005234 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005235}
5236
5237
5238/*============================================================================*/
5239/**
5240* \brief Reset QAM block.
5241* \param demod: instance of demod.
5242* \param channel: pointer to channel data.
5243* \return DRXStatus_t.
5244*/
5245static int QAMResetQAM(struct drxk_state *state)
5246{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005247 int status;
5248 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005249
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005250 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005251 /* Stop QAM comstate->m_exec */
5252 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5253 if (status < 0)
5254 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005255
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005256 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5257error:
5258 if (status < 0)
5259 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005260 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005261}
5262
5263/*============================================================================*/
5264
5265/**
5266* \brief Set QAM symbolrate.
5267* \param demod: instance of demod.
5268* \param channel: pointer to channel data.
5269* \return DRXStatus_t.
5270*/
5271static int QAMSetSymbolrate(struct drxk_state *state)
5272{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005273 u32 adcFrequency = 0;
5274 u32 symbFreq = 0;
5275 u32 iqmRcRate = 0;
5276 u16 ratesel = 0;
5277 u32 lcSymbRate = 0;
5278 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005279
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005280 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005281 /* Select & calculate correct IQM rate */
5282 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5283 ratesel = 0;
5284 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
5285 if (state->param.u.qam.symbol_rate <= 1188750)
5286 ratesel = 3;
5287 else if (state->param.u.qam.symbol_rate <= 2377500)
5288 ratesel = 2;
5289 else if (state->param.u.qam.symbol_rate <= 4755000)
5290 ratesel = 1;
5291 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5292 if (status < 0)
5293 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005294
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005295 /*
5296 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5297 */
5298 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5299 if (symbFreq == 0) {
5300 /* Divide by zero */
5301 status = -EINVAL;
5302 goto error;
5303 }
5304 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5305 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5306 (1 << 23);
5307 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5308 if (status < 0)
5309 goto error;
5310 state->m_iqmRcRate = iqmRcRate;
5311 /*
5312 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5313 */
5314 symbFreq = state->param.u.qam.symbol_rate;
5315 if (adcFrequency == 0) {
5316 /* Divide by zero */
5317 status = -EINVAL;
5318 goto error;
5319 }
5320 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5321 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5322 16);
5323 if (lcSymbRate > 511)
5324 lcSymbRate = 511;
5325 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005326
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005327error:
5328 if (status < 0)
5329 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005330 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005331}
5332
5333/*============================================================================*/
5334
5335/**
5336* \brief Get QAM lock status.
5337* \param demod: instance of demod.
5338* \param channel: pointer to channel data.
5339* \return DRXStatus_t.
5340*/
5341
5342static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5343{
5344 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005345 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005346
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005347 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005348 *pLockStatus = NOT_LOCKED;
5349 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005350 SCU_RAM_COMMAND_STANDARD_QAM |
5351 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5352 Result);
5353 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005354 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005355
5356 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005357 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005358 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005359 /* 0x4000 DEMOD LOCKED */
5360 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005361 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005362 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5363 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005364 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005365 /* 0xC000 NEVER LOCKED */
5366 /* (system will never be able to lock to the signal) */
5367 /* TODO: check this, intermediate & standard specific lock states are not
5368 taken into account here */
5369 *pLockStatus = NEVER_LOCK;
5370 }
5371 return status;
5372}
5373
5374#define QAM_MIRROR__M 0x03
5375#define QAM_MIRROR_NORMAL 0x00
5376#define QAM_MIRRORED 0x01
5377#define QAM_MIRROR_AUTO_ON 0x02
5378#define QAM_LOCKRANGE__M 0x10
5379#define QAM_LOCKRANGE_NORMAL 0x10
5380
Oliver Endrissebc7de22011-07-03 13:49:44 -03005381static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5382 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005383{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005384 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005385 u8 parameterLen;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005386 u16 setEnvParameters[5];
5387 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5388 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005389
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005390 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005391 /*
5392 STEP 1: reset demodulator
5393 resets FEC DI and FEC RS
5394 resets QAM block
5395 resets SCU variables
5396 */
5397 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005398 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005399 goto error;
5400 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5401 if (status < 0)
5402 goto error;
5403 status = QAMResetQAM(state);
5404 if (status < 0)
5405 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005406
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005407 /*
5408 STEP 2: configure demodulator
5409 -set env
5410 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5411 */
5412 status = QAMSetSymbolrate(state);
5413 if (status < 0)
5414 goto error;
5415
5416 /* Env parameters */
5417 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
5418 if (state->m_OperationMode == OM_QAM_ITU_C)
5419 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
5420 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5421 /* check for LOCKRANGE Extented */
5422 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5423 parameterLen = 4;
5424
5425 /* Set params */
5426 switch (state->param.u.qam.modulation) {
5427 case QAM_256:
5428 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5429 break;
5430 case QAM_AUTO:
5431 case QAM_64:
5432 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5433 break;
5434 case QAM_16:
5435 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5436 break;
5437 case QAM_32:
5438 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5439 break;
5440 case QAM_128:
5441 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5442 break;
5443 default:
5444 status = -EINVAL;
5445 break;
5446 }
5447 if (status < 0)
5448 goto error;
5449 setParamParameters[0] = state->m_Constellation; /* constellation */
5450 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5451
5452 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5453 if (status < 0)
5454 goto error;
5455
5456
5457 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5458 setup constellation independent registers */
5459#if 0
5460 status = SetFrequency(channel, tunerFreqOffset));
5461 if (status < 0)
5462 goto error;
5463#endif
5464 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5465 if (status < 0)
5466 goto error;
5467
5468 /* Setup BER measurement */
5469 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5470 if (status < 0)
5471 goto error;
5472
5473 /* Reset default values */
5474 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5475 if (status < 0)
5476 goto error;
5477 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5478 if (status < 0)
5479 goto error;
5480
5481 /* Reset default LC values */
5482 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5483 if (status < 0)
5484 goto error;
5485 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5486 if (status < 0)
5487 goto error;
5488 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5489 if (status < 0)
5490 goto error;
5491 status = write16(state, QAM_LC_MODE__A, 7);
5492 if (status < 0)
5493 goto error;
5494
5495 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5496 if (status < 0)
5497 goto error;
5498 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5499 if (status < 0)
5500 goto error;
5501 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5502 if (status < 0)
5503 goto error;
5504 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5505 if (status < 0)
5506 goto error;
5507 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5508 if (status < 0)
5509 goto error;
5510 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5511 if (status < 0)
5512 goto error;
5513 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5514 if (status < 0)
5515 goto error;
5516 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5517 if (status < 0)
5518 goto error;
5519 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5520 if (status < 0)
5521 goto error;
5522 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5523 if (status < 0)
5524 goto error;
5525 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5526 if (status < 0)
5527 goto error;
5528 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5529 if (status < 0)
5530 goto error;
5531 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5532 if (status < 0)
5533 goto error;
5534 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5535 if (status < 0)
5536 goto error;
5537 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5538 if (status < 0)
5539 goto error;
5540
5541 /* Mirroring, QAM-block starting point not inverted */
5542 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5543 if (status < 0)
5544 goto error;
5545
5546 /* Halt SCU to enable safe non-atomic accesses */
5547 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5548 if (status < 0)
5549 goto error;
5550
5551 /* STEP 4: constellation specific setup */
5552 switch (state->param.u.qam.modulation) {
5553 case QAM_16:
5554 status = SetQAM16(state);
5555 break;
5556 case QAM_32:
5557 status = SetQAM32(state);
5558 break;
5559 case QAM_AUTO:
5560 case QAM_64:
5561 status = SetQAM64(state);
5562 break;
5563 case QAM_128:
5564 status = SetQAM128(state);
5565 break;
5566 case QAM_256:
5567 status = SetQAM256(state);
5568 break;
5569 default:
5570 status = -EINVAL;
5571 break;
5572 }
5573 if (status < 0)
5574 goto error;
5575
5576 /* Activate SCU to enable SCU commands */
5577 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5578 if (status < 0)
5579 goto error;
5580
5581 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5582 /* extAttr->currentChannel.constellation = channel->constellation; */
5583 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5584 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5585 if (status < 0)
5586 goto error;
5587
5588 /* Start processes */
5589 status = MPEGTSStart(state);
5590 if (status < 0)
5591 goto error;
5592 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5593 if (status < 0)
5594 goto error;
5595 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5596 if (status < 0)
5597 goto error;
5598 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5599 if (status < 0)
5600 goto error;
5601
5602 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5603 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5604 if (status < 0)
5605 goto error;
5606
5607 /* update global DRXK data container */
5608/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5609
5610error:
5611 if (status < 0)
5612 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005613 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005614}
5615
Oliver Endrissebc7de22011-07-03 13:49:44 -03005616static int SetQAMStandard(struct drxk_state *state,
5617 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005618{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005619 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005620#ifdef DRXK_QAM_TAPS
5621#define DRXK_QAMA_TAPS_SELECT
5622#include "drxk_filters.h"
5623#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005624#endif
5625
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005626 /* added antenna switch */
5627 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005628
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005629 /* Ensure correct power-up mode */
5630 status = PowerUpQAM(state);
5631 if (status < 0)
5632 goto error;
5633 /* Reset QAM block */
5634 status = QAMResetQAM(state);
5635 if (status < 0)
5636 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005637
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005638 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005639
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005640 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5641 if (status < 0)
5642 goto error;
5643 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5644 if (status < 0)
5645 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005646
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005647 /* Upload IQM Channel Filter settings by
5648 boot loader from ROM table */
5649 switch (oMode) {
5650 case OM_QAM_ITU_A:
5651 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5652 break;
5653 case OM_QAM_ITU_C:
5654 status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005655 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005656 goto error;
5657 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5658 break;
5659 default:
5660 status = -EINVAL;
5661 }
5662 if (status < 0)
5663 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005664
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005665 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5666 if (status < 0)
5667 goto error;
5668 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5669 if (status < 0)
5670 goto error;
5671 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5672 if (status < 0)
5673 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005674
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005675 status = write16(state, IQM_RC_STRETCH__A, 21);
5676 if (status < 0)
5677 goto error;
5678 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5679 if (status < 0)
5680 goto error;
5681 status = write16(state, IQM_AF_CLP_TH__A, 448);
5682 if (status < 0)
5683 goto error;
5684 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5685 if (status < 0)
5686 goto error;
5687 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5688 if (status < 0)
5689 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005690
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005691 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5692 if (status < 0)
5693 goto error;
5694 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5695 if (status < 0)
5696 goto error;
5697 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5698 if (status < 0)
5699 goto error;
5700 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5701 if (status < 0)
5702 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005703
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005704 /* IQM Impulse Noise Processing Unit */
5705 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5706 if (status < 0)
5707 goto error;
5708 status = write16(state, IQM_CF_DATATH__A, 1000);
5709 if (status < 0)
5710 goto error;
5711 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5712 if (status < 0)
5713 goto error;
5714 status = write16(state, IQM_CF_DET_LCT__A, 0);
5715 if (status < 0)
5716 goto error;
5717 status = write16(state, IQM_CF_WND_LEN__A, 1);
5718 if (status < 0)
5719 goto error;
5720 status = write16(state, IQM_CF_PKDTH__A, 1);
5721 if (status < 0)
5722 goto error;
5723 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5724 if (status < 0)
5725 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005726
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005727 /* turn on IQMAF. Must be done before setAgc**() */
5728 status = SetIqmAf(state, true);
5729 if (status < 0)
5730 goto error;
5731 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5732 if (status < 0)
5733 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005734
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005735 /* IQM will not be reset from here, sync ADC and update/init AGC */
5736 status = ADCSynchronization(state);
5737 if (status < 0)
5738 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005739
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005740 /* Set the FSM step period */
5741 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5742 if (status < 0)
5743 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005744
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005745 /* Halt SCU to enable safe non-atomic accesses */
5746 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5747 if (status < 0)
5748 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005749
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005750 /* No more resets of the IQM, current standard correctly set =>
5751 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005752
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005753 status = InitAGC(state, true);
5754 if (status < 0)
5755 goto error;
5756 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5757 if (status < 0)
5758 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005759
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005760 /* Configure AGC's */
5761 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5762 if (status < 0)
5763 goto error;
5764 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5765 if (status < 0)
5766 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005767
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005768 /* Activate SCU to enable SCU commands */
5769 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5770error:
5771 if (status < 0)
5772 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005773 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005774}
5775
5776static int WriteGPIO(struct drxk_state *state)
5777{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005778 int status;
5779 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005780
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005781 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005782 /* stop lock indicator process */
5783 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5784 if (status < 0)
5785 goto error;
5786
5787 /* Write magic word to enable pdr reg write */
5788 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5789 if (status < 0)
5790 goto error;
5791
5792 if (state->m_hasSAWSW) {
5793 /* write to io pad configuration register - output mode */
5794 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005795 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005796 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005797
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005798 /* use corresponding bit in io data output registar */
5799 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005800 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005801 goto error;
5802 if (state->m_GPIO == 0)
5803 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5804 else
5805 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5806 /* write back to io data output register */
5807 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005808 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005809 goto error;
5810
5811 }
5812 /* Write magic word to disable pdr reg write */
5813 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5814error:
5815 if (status < 0)
5816 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005817 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005818}
5819
5820static int SwitchAntennaToQAM(struct drxk_state *state)
5821{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005822 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005823
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005824 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03005825 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5826 if (state->m_GPIO != state->m_AntennaDVBC) {
5827 state->m_GPIO = state->m_AntennaDVBC;
5828 status = WriteGPIO(state);
5829 }
5830 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005831 if (status < 0)
5832 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005833 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005834}
5835
5836static int SwitchAntennaToDVBT(struct drxk_state *state)
5837{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005838 int status = -EINVAL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005839
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005840 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005841 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5842 if (state->m_GPIO != state->m_AntennaDVBT) {
5843 state->m_GPIO = state->m_AntennaDVBT;
5844 status = WriteGPIO(state);
5845 }
5846 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005847 if (status < 0)
5848 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005849 return status;
5850}
5851
5852
5853static int PowerDownDevice(struct drxk_state *state)
5854{
5855 /* Power down to requested mode */
5856 /* Backup some register settings */
5857 /* Set pins with possible pull-ups connected to them in input mode */
5858 /* Analog power down */
5859 /* ADC power down */
5860 /* Power down device */
5861 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005862
5863 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005864 if (state->m_bPDownOpenBridge) {
5865 /* Open I2C bridge before power down of DRXK */
5866 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005867 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005868 goto error;
5869 }
5870 /* driver 0.9.0 */
5871 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005872 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005873 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005874
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005875 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5876 if (status < 0)
5877 goto error;
5878 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5879 if (status < 0)
5880 goto error;
5881 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5882 status = HI_CfgCommand(state);
5883error:
5884 if (status < 0)
5885 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5886
5887 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005888}
5889
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005890static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005891{
5892 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005893 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005894
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005895 dprintk(1, "\n");
5896
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005897 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5898 if (err < 0) {
5899 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005900 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005901 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005902 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005903 return err;
5904 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005905 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005906 release_firmware(fw);
5907 return err;
5908}
5909
5910static int init_drxk(struct drxk_state *state)
5911{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005912 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005913 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005914 u16 driverVersion;
5915
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005916 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005917 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005918 status = PowerUpDevice(state);
5919 if (status < 0)
5920 goto error;
5921 status = DRXX_Open(state);
5922 if (status < 0)
5923 goto error;
5924 /* Soft reset of OFDM-, sys- and osc-clockdomain */
5925 status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
5926 if (status < 0)
5927 goto error;
5928 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5929 if (status < 0)
5930 goto error;
5931 /* TODO is this needed, if yes how much delay in worst case scenario */
5932 msleep(1);
5933 state->m_DRXK_A3_PATCH_CODE = true;
5934 status = GetDeviceCapabilities(state);
5935 if (status < 0)
5936 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005937
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005938 /* Bridge delay, uses oscilator clock */
5939 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5940 /* SDA brdige delay */
5941 state->m_HICfgBridgeDelay =
5942 (u16) ((state->m_oscClockFreq / 1000) *
5943 HI_I2C_BRIDGE_DELAY) / 1000;
5944 /* Clipping */
5945 if (state->m_HICfgBridgeDelay >
5946 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03005947 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005948 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
5949 }
5950 /* SCL bridge delay, same as SDA for now */
5951 state->m_HICfgBridgeDelay +=
5952 state->m_HICfgBridgeDelay <<
5953 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005954
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005955 status = InitHI(state);
5956 if (status < 0)
5957 goto error;
5958 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005959#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005960 if (!(state->m_DRXK_A1_ROM_CODE)
5961 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005962#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005963 {
5964 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5965 if (status < 0)
5966 goto error;
5967 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005968
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005969 /* disable MPEG port */
5970 status = MPEGTSDisable(state);
5971 if (status < 0)
5972 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005973
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005974 /* Stop AUD and SCU */
5975 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
5976 if (status < 0)
5977 goto error;
5978 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
5979 if (status < 0)
5980 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005981
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005982 /* enable token-ring bus through OFDM block for possible ucode upload */
5983 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
5984 if (status < 0)
5985 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005986
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005987 /* include boot loader section */
5988 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
5989 if (status < 0)
5990 goto error;
5991 status = BLChainCmd(state, 0, 6, 100);
5992 if (status < 0)
5993 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005994
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005995 if (!state->microcode_name)
5996 load_microcode(state, "drxk_a3.mc");
5997 else
5998 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005999
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006000 /* disable token-ring bus through OFDM block for possible ucode upload */
6001 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6002 if (status < 0)
6003 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006004
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006005 /* Run SCU for a little while to initialize microcode version numbers */
6006 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6007 if (status < 0)
6008 goto error;
6009 status = DRXX_Open(state);
6010 if (status < 0)
6011 goto error;
6012 /* added for test */
6013 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006014
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006015 powerMode = DRXK_POWER_DOWN_OFDM;
6016 status = CtrlPowerMode(state, &powerMode);
6017 if (status < 0)
6018 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006019
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006020 /* Stamp driver version number in SCU data RAM in BCD code
6021 Done to enable field application engineers to retreive drxdriver version
6022 via I2C from SCU RAM.
6023 Not using SCU command interface for SCU register access since no
6024 microcode may be present.
6025 */
6026 driverVersion =
6027 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6028 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6029 ((DRXK_VERSION_MAJOR % 10) << 4) +
6030 (DRXK_VERSION_MINOR % 10);
6031 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6032 if (status < 0)
6033 goto error;
6034 driverVersion =
6035 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6036 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6037 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6038 (DRXK_VERSION_PATCH % 10);
6039 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6040 if (status < 0)
6041 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006042
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006043 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6044 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6045 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006046
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006047 /* Dirty fix of default values for ROM/PATCH microcode
6048 Dirty because this fix makes it impossible to setup suitable values
6049 before calling DRX_Open. This solution requires changes to RF AGC speed
6050 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006051
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006052 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006053
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006054 /* Reset driver debug flags to 0 */
6055 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6056 if (status < 0)
6057 goto error;
6058 /* driver 0.9.0 */
6059 /* Setup FEC OC:
6060 NOTE: No more full FEC resets allowed afterwards!! */
6061 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6062 if (status < 0)
6063 goto error;
6064 /* MPEGTS functions are still the same */
6065 status = MPEGTSDtoInit(state);
6066 if (status < 0)
6067 goto error;
6068 status = MPEGTSStop(state);
6069 if (status < 0)
6070 goto error;
6071 status = MPEGTSConfigurePolarity(state);
6072 if (status < 0)
6073 goto error;
6074 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6075 if (status < 0)
6076 goto error;
6077 /* added: configure GPIO */
6078 status = WriteGPIO(state);
6079 if (status < 0)
6080 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006081
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006082 state->m_DrxkState = DRXK_STOPPED;
6083
6084 if (state->m_bPowerDown) {
6085 status = PowerDownDevice(state);
6086 if (status < 0)
6087 goto error;
6088 state->m_DrxkState = DRXK_POWERED_DOWN;
6089 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006090 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006091 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006092error:
6093 if (status < 0)
6094 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006095
6096 return 0;
6097}
6098
Oliver Endrissebc7de22011-07-03 13:49:44 -03006099static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006100{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006101 struct drxk_state *state = fe->demodulator_priv;
6102
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006103 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006104 kfree(state);
6105}
6106
Oliver Endrissebc7de22011-07-03 13:49:44 -03006107static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006108{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006109 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006110
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006111 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006112 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006113 return -EBUSY;
6114 SetOperationMode(state, OM_QAM_ITU_A);
6115 return 0;
6116}
6117
Oliver Endrissebc7de22011-07-03 13:49:44 -03006118static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006119{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006120 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006121
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006122 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006123 ShutDown(state);
6124 mutex_unlock(&state->ctlock);
6125 return 0;
6126}
6127
Oliver Endrissebc7de22011-07-03 13:49:44 -03006128static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006129{
6130 struct drxk_state *state = fe->demodulator_priv;
6131
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006132 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006133 return ConfigureI2CBridge(state, enable ? true : false);
6134}
6135
Oliver Endrissebc7de22011-07-03 13:49:44 -03006136static int drxk_set_parameters(struct dvb_frontend *fe,
6137 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006138{
6139 struct drxk_state *state = fe->demodulator_priv;
6140 u32 IF;
6141
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006142 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006143 if (fe->ops.i2c_gate_ctrl)
6144 fe->ops.i2c_gate_ctrl(fe, 1);
6145 if (fe->ops.tuner_ops.set_params)
6146 fe->ops.tuner_ops.set_params(fe, p);
6147 if (fe->ops.i2c_gate_ctrl)
6148 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006149 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006150 fe->ops.tuner_ops.get_frequency(fe, &IF);
6151 Start(state, 0, IF);
6152
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006153 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006154
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006155 return 0;
6156}
6157
Oliver Endrissebc7de22011-07-03 13:49:44 -03006158static int drxk_c_get_frontend(struct dvb_frontend *fe,
6159 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006160{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006161 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006162 return 0;
6163}
6164
6165static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6166{
6167 struct drxk_state *state = fe->demodulator_priv;
6168 u32 stat;
6169
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006170 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006171 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006172 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006173 if (stat == MPEG_LOCK)
6174 *status |= 0x1f;
6175 if (stat == FEC_LOCK)
6176 *status |= 0x0f;
6177 if (stat == DEMOD_LOCK)
6178 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006179 return 0;
6180}
6181
6182static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6183{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006184 dprintk(1, "\n");
6185
Oliver Endrissebc7de22011-07-03 13:49:44 -03006186 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006187 return 0;
6188}
6189
Oliver Endrissebc7de22011-07-03 13:49:44 -03006190static int drxk_read_signal_strength(struct dvb_frontend *fe,
6191 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006192{
6193 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006194 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006195
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006196 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006197 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006198 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006199 return 0;
6200}
6201
6202static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6203{
6204 struct drxk_state *state = fe->demodulator_priv;
6205 s32 snr2;
6206
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006207 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006208 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006209 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006210 return 0;
6211}
6212
6213static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6214{
6215 struct drxk_state *state = fe->demodulator_priv;
6216 u16 err;
6217
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006218 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006219 DVBTQAMGetAccPktErr(state, &err);
6220 *ucblocks = (u32) err;
6221 return 0;
6222}
6223
Oliver Endrissebc7de22011-07-03 13:49:44 -03006224static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6225 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006226{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006227 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006228 sets->min_delay_ms = 3000;
6229 sets->max_drift = 0;
6230 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006231 return 0;
6232}
6233
Oliver Endrissebc7de22011-07-03 13:49:44 -03006234static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006235{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006236#if 0
6237 struct drxk_state *state = fe->demodulator_priv;
6238
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006239 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006240 kfree(state);
6241#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006242}
6243
Oliver Endrissebc7de22011-07-03 13:49:44 -03006244static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006245{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006246 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006247
6248 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006249 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006250 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006251 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006252 return 0;
6253}
6254
Oliver Endrissebc7de22011-07-03 13:49:44 -03006255static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006256{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006257 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006258
6259 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006260 mutex_unlock(&state->ctlock);
6261 return 0;
6262}
6263
Oliver Endrissebc7de22011-07-03 13:49:44 -03006264static int drxk_t_get_frontend(struct dvb_frontend *fe,
6265 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006266{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006267 dprintk(1, "\n");
6268
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006269 return 0;
6270}
6271
6272static struct dvb_frontend_ops drxk_c_ops = {
6273 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006274 .name = "DRXK DVB-C",
6275 .type = FE_QAM,
6276 .frequency_stepsize = 62500,
6277 .frequency_min = 47000000,
6278 .frequency_max = 862000000,
6279 .symbol_rate_min = 870000,
6280 .symbol_rate_max = 11700000,
6281 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6282 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006283 .release = drxk_c_release,
6284 .init = drxk_c_init,
6285 .sleep = drxk_c_sleep,
6286 .i2c_gate_ctrl = drxk_gate_ctrl,
6287
6288 .set_frontend = drxk_set_parameters,
6289 .get_frontend = drxk_c_get_frontend,
6290 .get_tune_settings = drxk_c_get_tune_settings,
6291
6292 .read_status = drxk_read_status,
6293 .read_ber = drxk_read_ber,
6294 .read_signal_strength = drxk_read_signal_strength,
6295 .read_snr = drxk_read_snr,
6296 .read_ucblocks = drxk_read_ucblocks,
6297};
6298
6299static struct dvb_frontend_ops drxk_t_ops = {
6300 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006301 .name = "DRXK DVB-T",
6302 .type = FE_OFDM,
6303 .frequency_min = 47125000,
6304 .frequency_max = 865000000,
6305 .frequency_stepsize = 166667,
6306 .frequency_tolerance = 0,
6307 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6308 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6309 FE_CAN_FEC_AUTO |
6310 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6311 FE_CAN_QAM_AUTO |
6312 FE_CAN_TRANSMISSION_MODE_AUTO |
6313 FE_CAN_GUARD_INTERVAL_AUTO |
6314 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006315 .release = drxk_t_release,
6316 .init = drxk_t_init,
6317 .sleep = drxk_t_sleep,
6318 .i2c_gate_ctrl = drxk_gate_ctrl,
6319
6320 .set_frontend = drxk_set_parameters,
6321 .get_frontend = drxk_t_get_frontend,
6322
6323 .read_status = drxk_read_status,
6324 .read_ber = drxk_read_ber,
6325 .read_signal_strength = drxk_read_signal_strength,
6326 .read_snr = drxk_read_snr,
6327 .read_ucblocks = drxk_read_ucblocks,
6328};
6329
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006330struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6331 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006332 struct dvb_frontend **fe_t)
6333{
6334 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006335 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006336
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006337 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006338 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006339 if (!state)
6340 return NULL;
6341
Oliver Endrissebc7de22011-07-03 13:49:44 -03006342 state->i2c = i2c;
6343 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006344 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006345 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006346 state->no_i2c_bridge = config->no_i2c_bridge;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006347
6348 mutex_init(&state->mutex);
6349 mutex_init(&state->ctlock);
6350
Oliver Endrissebc7de22011-07-03 13:49:44 -03006351 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6352 sizeof(struct dvb_frontend_ops));
6353 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6354 sizeof(struct dvb_frontend_ops));
6355 state->c_frontend.demodulator_priv = state;
6356 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006357
6358 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006359 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006360 goto error;
6361 *fe_t = &state->t_frontend;
6362 return &state->c_frontend;
6363
6364error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006365 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006366 kfree(state);
6367 return NULL;
6368}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006369EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006370
6371MODULE_DESCRIPTION("DRX-K driver");
6372MODULE_AUTHOR("Ralph Metzler");
6373MODULE_LICENSE("GPL");