blob: 85332e83044752701e02599d42a32a6848e48f22 [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 Chehabf07a0bc2011-07-21 22:30:27 -0300358
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300359 status = i2c_transfer(adap, msgs, 2);
360 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300361 if (debug > 2)
362 printk(KERN_CONT ": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300363 if (status >= 0)
364 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300365
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300366 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300367 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300368 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300369 if (debug > 2) {
370 int i;
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300371 dprintk(2, ": read from ");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300372 for (i = 0; i < len; i++)
373 printk(KERN_CONT " %02x", msg[i]);
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300374 printk(KERN_CONT "Value = ");
375 for (i = 0; i < alen; i++)
376 printk(KERN_CONT " %02x", answ[i]);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300377 printk(KERN_CONT "\n");
378 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300379 return 0;
380}
381
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300382static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300383{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300384 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300385 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300386
387 if (state->single_master)
388 flags |= 0xC0;
389
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300390 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
391 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
392 mm1[1] = ((reg >> 16) & 0xFF);
393 mm1[2] = ((reg >> 24) & 0xFF) | flags;
394 mm1[3] = ((reg >> 7) & 0xFF);
395 len = 4;
396 } else {
397 mm1[0] = ((reg << 1) & 0xFF);
398 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
399 len = 2;
400 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300401 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300402 status = i2c_read(state->i2c, adr, mm1, len, mm2, 2);
403 if (status < 0)
404 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300405 if (data)
406 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300407
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300408 return 0;
409}
410
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300411static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300412{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300413 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300414}
415
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300416static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300417{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300418 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300419 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300420
421 if (state->single_master)
422 flags |= 0xC0;
423
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300424 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
425 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
426 mm1[1] = ((reg >> 16) & 0xFF);
427 mm1[2] = ((reg >> 24) & 0xFF) | flags;
428 mm1[3] = ((reg >> 7) & 0xFF);
429 len = 4;
430 } else {
431 mm1[0] = ((reg << 1) & 0xFF);
432 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
433 len = 2;
434 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300435 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300436 status = i2c_read(state->i2c, adr, mm1, len, mm2, 4);
437 if (status < 0)
438 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300439 if (data)
440 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300441 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300442
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300443 return 0;
444}
445
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300446static int read32(struct drxk_state *state, u32 reg, u32 *data)
447{
448 return read32_flags(state, reg, data, 0);
449}
450
451static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300452{
453 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300454
455 if (state->single_master)
456 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300457 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
458 mm[0] = (((reg << 1) & 0xFF) | 0x01);
459 mm[1] = ((reg >> 16) & 0xFF);
460 mm[2] = ((reg >> 24) & 0xFF) | flags;
461 mm[3] = ((reg >> 7) & 0xFF);
462 len = 4;
463 } else {
464 mm[0] = ((reg << 1) & 0xFF);
465 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
466 len = 2;
467 }
468 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300469 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300470
471 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300472 return i2c_write(state->i2c, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300473}
474
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300475static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300476{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300477 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300478}
479
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300480static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300481{
482 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300483
484 if (state->single_master)
485 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300486 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
487 mm[0] = (((reg << 1) & 0xFF) | 0x01);
488 mm[1] = ((reg >> 16) & 0xFF);
489 mm[2] = ((reg >> 24) & 0xFF) | flags;
490 mm[3] = ((reg >> 7) & 0xFF);
491 len = 4;
492 } else {
493 mm[0] = ((reg << 1) & 0xFF);
494 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
495 len = 2;
496 }
497 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300498 mm[len + 1] = (data >> 8) & 0xff;
499 mm[len + 2] = (data >> 16) & 0xff;
500 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300501 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300502
503 return i2c_write(state->i2c, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300504}
505
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300506static int write32(struct drxk_state *state, u32 reg, u32 data)
507{
508 return write32_flags(state, reg, data, 0);
509}
510
511static int write_block(struct drxk_state *state, u32 Address,
512 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300513{
514 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300515 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300516
517 if (state->single_master)
518 Flags |= 0xC0;
519
Oliver Endrissebc7de22011-07-03 13:49:44 -0300520 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300521 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300522 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300523 u8 *AdrBuf = &state->Chunk[0];
524 u32 AdrLength = 0;
525
Oliver Endrissebc7de22011-07-03 13:49:44 -0300526 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
527 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
528 AdrBuf[1] = ((Address >> 16) & 0xFF);
529 AdrBuf[2] = ((Address >> 24) & 0xFF);
530 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300531 AdrBuf[2] |= Flags;
532 AdrLength = 4;
533 if (Chunk == state->m_ChunkSize)
534 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300535 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300536 AdrBuf[0] = ((Address << 1) & 0xFF);
537 AdrBuf[1] = (((Address >> 16) & 0x0F) |
538 ((Address >> 18) & 0xF0));
539 AdrLength = 2;
540 }
541 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300542 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
543 if (debug > 1) {
544 int i;
545 if (pBlock)
546 for (i = 0; i < Chunk; i++)
547 printk(KERN_CONT " %02x", pBlock[i]);
548 printk(KERN_CONT "\n");
549 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300550 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300551 &state->Chunk[0], Chunk + AdrLength);
552 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300553 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
554 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300555 break;
556 }
557 pBlock += Chunk;
558 Address += (Chunk >> 1);
559 BlkSize -= Chunk;
560 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300561 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300562}
563
564#ifndef DRXK_MAX_RETRIES_POWERUP
565#define DRXK_MAX_RETRIES_POWERUP 20
566#endif
567
568int PowerUpDevice(struct drxk_state *state)
569{
570 int status;
571 u8 data = 0;
572 u16 retryCount = 0;
573
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300574 dprintk(1, "\n");
575
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300576 status = i2c_read1(state->i2c, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300577 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300578 do {
579 data = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300580 status = i2c_write(state->i2c, state->demod_address,
581 &data, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300582 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300583 retryCount++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300584 if (status < 0)
585 continue;
586 status = i2c_read1(state->i2c, state->demod_address,
587 &data);
588 } while (status < 0 &&
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300589 (retryCount < DRXK_MAX_RETRIES_POWERUP));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300590 if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
591 goto error;
592 }
593
594 /* Make sure all clk domains are active */
595 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
596 if (status < 0)
597 goto error;
598 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
599 if (status < 0)
600 goto error;
601 /* Enable pll lock tests */
602 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
603 if (status < 0)
604 goto error;
605
606 state->m_currentPowerMode = DRX_POWER_UP;
607
608error:
609 if (status < 0)
610 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
611
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300612 return status;
613}
614
615
616static int init_state(struct drxk_state *state)
617{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -0300618 /*
619 * FIXME: most (all?) of the values bellow should be moved into
620 * struct drxk_config, as they are probably board-specific
621 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300622 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
623 u32 ulVSBIfAgcOutputLevel = 0;
624 u32 ulVSBIfAgcMinLevel = 0;
625 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
626 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300627
Oliver Endrissebc7de22011-07-03 13:49:44 -0300628 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
629 u32 ulVSBRfAgcOutputLevel = 0;
630 u32 ulVSBRfAgcMinLevel = 0;
631 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
632 u32 ulVSBRfAgcSpeed = 3;
633 u32 ulVSBRfAgcTop = 9500;
634 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300635
Oliver Endrissebc7de22011-07-03 13:49:44 -0300636 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
637 u32 ulATVIfAgcOutputLevel = 0;
638 u32 ulATVIfAgcMinLevel = 0;
639 u32 ulATVIfAgcMaxLevel = 0;
640 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300641
Oliver Endrissebc7de22011-07-03 13:49:44 -0300642 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
643 u32 ulATVRfAgcOutputLevel = 0;
644 u32 ulATVRfAgcMinLevel = 0;
645 u32 ulATVRfAgcMaxLevel = 0;
646 u32 ulATVRfAgcTop = 9500;
647 u32 ulATVRfAgcCutOffCurrent = 4000;
648 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300649
650 u32 ulQual83 = DEFAULT_MER_83;
651 u32 ulQual93 = DEFAULT_MER_93;
652
653 u32 ulDVBTStaticTSClock = 1;
654 u32 ulDVBCStaticTSClock = 1;
655
656 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
657 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
658
659 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
660 /* io_pad_cfg_mode output mode is drive always */
661 /* io_pad_cfg_drive is set to power 2 (23 mA) */
662 u32 ulGPIOCfg = 0x0113;
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
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300675 dprintk(1, "\n");
676
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300677 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300678 state->m_hasDVBT = false;
679 state->m_hasDVBC = false;
680 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300681 state->m_hasOOB = false;
682 state->m_hasAudio = false;
683
684 state->m_ChunkSize = 124;
685
686 state->m_oscClockFreq = 0;
687 state->m_smartAntInverted = false;
688 state->m_bPDownOpenBridge = false;
689
690 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300691 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300692 /* Timing div, 250ns/Psys */
693 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
694 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
695 HI_I2C_DELAY) / 1000;
696 /* Clipping */
697 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
698 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
699 state->m_HICfgWakeUpKey = (state->demod_address << 1);
700 /* port/bridge/power down ctrl */
701 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
702
703 state->m_bPowerDown = (ulPowerDown != 0);
704
705 state->m_DRXK_A1_PATCH_CODE = false;
706 state->m_DRXK_A1_ROM_CODE = false;
707 state->m_DRXK_A2_ROM_CODE = false;
708 state->m_DRXK_A3_ROM_CODE = false;
709 state->m_DRXK_A2_PATCH_CODE = false;
710 state->m_DRXK_A3_PATCH_CODE = false;
711
712 /* Init AGC and PGA parameters */
713 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300714 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
715 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
716 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
717 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
718 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300719 state->m_vsbPgaCfg = 140;
720
721 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300722 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
723 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
724 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
725 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
726 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
727 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
728 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
729 state->m_vsbPreSawCfg.reference = 0x07;
730 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300731
732 state->m_Quality83percent = DEFAULT_MER_83;
733 state->m_Quality93percent = DEFAULT_MER_93;
734 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
735 state->m_Quality83percent = ulQual83;
736 state->m_Quality93percent = ulQual93;
737 }
738
739 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300740 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
741 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
742 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
743 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
744 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300745
746 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300747 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
748 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
749 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
750 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
751 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
752 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
753 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
754 state->m_atvPreSawCfg.reference = 0x04;
755 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300756
757
758 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300759 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
760 state->m_dvbtRfAgcCfg.outputLevel = 0;
761 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
762 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
763 state->m_dvbtRfAgcCfg.top = 0x2100;
764 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
765 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300766
767
768 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300769 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
770 state->m_dvbtIfAgcCfg.outputLevel = 0;
771 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
772 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
773 state->m_dvbtIfAgcCfg.top = 13424;
774 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
775 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300776 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300777 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
778 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300779
Oliver Endrissebc7de22011-07-03 13:49:44 -0300780 state->m_dvbtPreSawCfg.reference = 4;
781 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300782
783 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300784 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
785 state->m_qamRfAgcCfg.outputLevel = 0;
786 state->m_qamRfAgcCfg.minOutputLevel = 6023;
787 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
788 state->m_qamRfAgcCfg.top = 0x2380;
789 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
790 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300791
792 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300793 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
794 state->m_qamIfAgcCfg.outputLevel = 0;
795 state->m_qamIfAgcCfg.minOutputLevel = 0;
796 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
797 state->m_qamIfAgcCfg.top = 0x0511;
798 state->m_qamIfAgcCfg.cutOffCurrent = 0;
799 state->m_qamIfAgcCfg.speed = 3;
800 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300801 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
802
Oliver Endrissebc7de22011-07-03 13:49:44 -0300803 state->m_qamPgaCfg = 140;
804 state->m_qamPreSawCfg.reference = 4;
805 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300806
807 state->m_OperationMode = OM_NONE;
808 state->m_DrxkState = DRXK_UNINITIALIZED;
809
810 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300811 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
812 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
813 state->m_enableParallel = true; /* If TRUE;
814 parallel out otherwise serial */
815 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
816 state->m_invertERR = false; /* If TRUE; invert ERR signal */
817 state->m_invertSTR = false; /* If TRUE; invert STR signals */
818 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
819 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300820 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300821 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300822 /* If TRUE; static MPEG clockrate will be used;
823 otherwise clockrate will adapt to the bitrate of the TS */
824
825 state->m_DVBTBitrate = ulDVBTBitrate;
826 state->m_DVBCBitrate = ulDVBCBitrate;
827
828 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
829 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
830
831 /* Maximum bitrate in b/s in case static clockrate is selected */
832 state->m_mpegTsStaticBitrate = 19392658;
833 state->m_disableTEIhandling = false;
834
835 if (ulInsertRSByte)
836 state->m_insertRSByte = true;
837
838 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
839 if (ulMpegLockTimeOut < 10000)
840 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
841 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
842 if (ulDemodLockTimeOut < 10000)
843 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
844
Oliver Endrissebc7de22011-07-03 13:49:44 -0300845 /* QAM defaults */
846 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300847 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300848 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
849 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300850
851 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
852 state->m_agcFastClipCtrlDelay = 0;
853
854 state->m_GPIOCfg = (ulGPIOCfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300855
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300856 state->m_bPowerDown = false;
857 state->m_currentPowerMode = DRX_POWER_DOWN;
858
859 state->m_enableParallel = (ulSerialMode == 0);
860
861 state->m_rfmirror = (ulRfMirror == 0);
862 state->m_IfAgcPol = false;
863 return 0;
864}
865
866static int DRXX_Open(struct drxk_state *state)
867{
868 int status = 0;
869 u32 jtag = 0;
870 u16 bid = 0;
871 u16 key = 0;
872
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300873 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300874 /* stop lock indicator process */
875 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
876 if (status < 0)
877 goto error;
878 /* Check device id */
879 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
880 if (status < 0)
881 goto error;
882 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
883 if (status < 0)
884 goto error;
885 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
886 if (status < 0)
887 goto error;
888 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
889 if (status < 0)
890 goto error;
891 status = write16(state, SIO_TOP_COMM_KEY__A, key);
892error:
893 if (status < 0)
894 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300895 return status;
896}
897
898static int GetDeviceCapabilities(struct drxk_state *state)
899{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300900 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300901 u32 sioTopJtagidLo = 0;
902 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300903 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300904
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300905 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300906
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300907 /* driver 0.9.0 */
908 /* stop lock indicator process */
909 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
910 if (status < 0)
911 goto error;
912 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
913 if (status < 0)
914 goto error;
915 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
916 if (status < 0)
917 goto error;
918 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
919 if (status < 0)
920 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300921
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300922 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
923 case 0:
924 /* ignore (bypass ?) */
925 break;
926 case 1:
927 /* 27 MHz */
928 state->m_oscClockFreq = 27000;
929 break;
930 case 2:
931 /* 20.25 MHz */
932 state->m_oscClockFreq = 20250;
933 break;
934 case 3:
935 /* 4 MHz */
936 state->m_oscClockFreq = 20250;
937 break;
938 default:
939 printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
940 return -EINVAL;
941 }
942 /*
943 Determine device capabilities
944 Based on pinning v14
945 */
946 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
947 if (status < 0)
948 goto error;
949 /* driver 0.9.0 */
950 switch ((sioTopJtagidLo >> 29) & 0xF) {
951 case 0:
952 state->m_deviceSpin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300953 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300954 break;
955 case 2:
956 state->m_deviceSpin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300957 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300958 break;
959 case 3:
960 state->m_deviceSpin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300961 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300962 break;
963 default:
964 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
965 status = -EINVAL;
966 printk(KERN_ERR "drxk: Spin unknown\n");
967 goto error2;
968 }
969 switch ((sioTopJtagidLo >> 12) & 0xFF) {
970 case 0x13:
971 /* typeId = DRX3913K_TYPE_ID */
972 state->m_hasLNA = false;
973 state->m_hasOOB = false;
974 state->m_hasATV = false;
975 state->m_hasAudio = false;
976 state->m_hasDVBT = true;
977 state->m_hasDVBC = true;
978 state->m_hasSAWSW = true;
979 state->m_hasGPIO2 = false;
980 state->m_hasGPIO1 = false;
981 state->m_hasIRQN = false;
982 break;
983 case 0x15:
984 /* typeId = DRX3915K_TYPE_ID */
985 state->m_hasLNA = false;
986 state->m_hasOOB = false;
987 state->m_hasATV = true;
988 state->m_hasAudio = false;
989 state->m_hasDVBT = true;
990 state->m_hasDVBC = false;
991 state->m_hasSAWSW = true;
992 state->m_hasGPIO2 = true;
993 state->m_hasGPIO1 = true;
994 state->m_hasIRQN = false;
995 break;
996 case 0x16:
997 /* typeId = DRX3916K_TYPE_ID */
998 state->m_hasLNA = false;
999 state->m_hasOOB = false;
1000 state->m_hasATV = true;
1001 state->m_hasAudio = false;
1002 state->m_hasDVBT = true;
1003 state->m_hasDVBC = false;
1004 state->m_hasSAWSW = true;
1005 state->m_hasGPIO2 = true;
1006 state->m_hasGPIO1 = true;
1007 state->m_hasIRQN = false;
1008 break;
1009 case 0x18:
1010 /* typeId = DRX3918K_TYPE_ID */
1011 state->m_hasLNA = false;
1012 state->m_hasOOB = false;
1013 state->m_hasATV = true;
1014 state->m_hasAudio = true;
1015 state->m_hasDVBT = true;
1016 state->m_hasDVBC = false;
1017 state->m_hasSAWSW = true;
1018 state->m_hasGPIO2 = true;
1019 state->m_hasGPIO1 = true;
1020 state->m_hasIRQN = false;
1021 break;
1022 case 0x21:
1023 /* typeId = DRX3921K_TYPE_ID */
1024 state->m_hasLNA = false;
1025 state->m_hasOOB = false;
1026 state->m_hasATV = true;
1027 state->m_hasAudio = true;
1028 state->m_hasDVBT = true;
1029 state->m_hasDVBC = true;
1030 state->m_hasSAWSW = true;
1031 state->m_hasGPIO2 = true;
1032 state->m_hasGPIO1 = true;
1033 state->m_hasIRQN = false;
1034 break;
1035 case 0x23:
1036 /* typeId = DRX3923K_TYPE_ID */
1037 state->m_hasLNA = false;
1038 state->m_hasOOB = false;
1039 state->m_hasATV = true;
1040 state->m_hasAudio = true;
1041 state->m_hasDVBT = true;
1042 state->m_hasDVBC = true;
1043 state->m_hasSAWSW = true;
1044 state->m_hasGPIO2 = true;
1045 state->m_hasGPIO1 = true;
1046 state->m_hasIRQN = false;
1047 break;
1048 case 0x25:
1049 /* typeId = DRX3925K_TYPE_ID */
1050 state->m_hasLNA = false;
1051 state->m_hasOOB = false;
1052 state->m_hasATV = true;
1053 state->m_hasAudio = true;
1054 state->m_hasDVBT = true;
1055 state->m_hasDVBC = true;
1056 state->m_hasSAWSW = true;
1057 state->m_hasGPIO2 = true;
1058 state->m_hasGPIO1 = true;
1059 state->m_hasIRQN = false;
1060 break;
1061 case 0x26:
1062 /* typeId = DRX3926K_TYPE_ID */
1063 state->m_hasLNA = false;
1064 state->m_hasOOB = false;
1065 state->m_hasATV = true;
1066 state->m_hasAudio = false;
1067 state->m_hasDVBT = true;
1068 state->m_hasDVBC = true;
1069 state->m_hasSAWSW = true;
1070 state->m_hasGPIO2 = true;
1071 state->m_hasGPIO1 = true;
1072 state->m_hasIRQN = false;
1073 break;
1074 default:
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -03001075 printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001076 ((sioTopJtagidLo >> 12) & 0xFF));
1077 status = -EINVAL;
1078 goto error2;
1079 }
1080
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -03001081 printk(KERN_INFO
1082 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
1083 ((sioTopJtagidLo >> 12) & 0xFF), spin,
1084 state->m_oscClockFreq / 1000,
1085 state->m_oscClockFreq % 1000);
1086
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001087error:
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;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001520 const char *p;
1521 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001522
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001523 dprintk(1, "\n");
1524
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001525 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1526 ((resultLen > 0) && (result == NULL)))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001527 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001528
1529 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001530
1531 /* assume that the command register is ready
1532 since it is checked afterwards */
1533 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1534 buffer[cnt++] = (parameter[ii] & 0xFF);
1535 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1536 }
1537 buffer[cnt++] = (cmd & 0xFF);
1538 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1539
1540 write_block(state, SCU_RAM_PARAM_0__A -
1541 (parameterLen - 1), cnt, buffer);
1542 /* Wait until SCU has processed command */
1543 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001544 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001545 msleep(1);
1546 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1547 if (status < 0)
1548 goto error;
1549 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1550 if (curCmd != DRX_SCU_READY) {
1551 printk(KERN_ERR "drxk: SCU not ready\n");
1552 status = -EIO;
1553 goto error2;
1554 }
1555 /* read results */
1556 if ((resultLen > 0) && (result != NULL)) {
1557 s16 err;
1558 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001559
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001560 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1561 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001562 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001563 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001564 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001565
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001566 /* Check if an error was reported by SCU */
1567 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001568 if (err >= 0)
1569 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001570
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001571 /* check for the known error codes */
1572 switch (err) {
1573 case SCU_RESULT_UNKCMD:
1574 p = "SCU_RESULT_UNKCMD";
1575 break;
1576 case SCU_RESULT_UNKSTD:
1577 p = "SCU_RESULT_UNKSTD";
1578 break;
1579 case SCU_RESULT_SIZE:
1580 p = "SCU_RESULT_SIZE";
1581 break;
1582 case SCU_RESULT_INVPAR:
1583 p = "SCU_RESULT_INVPAR";
1584 break;
1585 default: /* Other negative values are errors */
1586 sprintf(errname, "ERROR: %d\n", err);
1587 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001588 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001589 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1590 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1591 status = -EINVAL;
1592 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001593 }
1594
1595error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001596 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001597 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001598error2:
1599 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001600 return status;
1601}
1602
1603static int SetIqmAf(struct drxk_state *state, bool active)
1604{
1605 u16 data = 0;
1606 int status;
1607
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001608 dprintk(1, "\n");
1609
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001610 /* Configure IQM */
1611 status = read16(state, IQM_AF_STDBY__A, &data);
1612 if (status < 0)
1613 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001614
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001615 if (!active) {
1616 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1617 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1618 | IQM_AF_STDBY_STDBY_PD_STANDBY
1619 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1620 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1621 } else {
1622 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1623 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1624 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1625 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1626 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1627 );
1628 }
1629 status = write16(state, IQM_AF_STDBY__A, data);
1630
1631error:
1632 if (status < 0)
1633 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001634 return status;
1635}
1636
Oliver Endrissebc7de22011-07-03 13:49:44 -03001637static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001638{
1639 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001640 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001641
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001642 dprintk(1, "\n");
1643
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001644 /* Check arguments */
1645 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001646 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001647
1648 switch (*mode) {
1649 case DRX_POWER_UP:
1650 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1651 break;
1652 case DRXK_POWER_DOWN_OFDM:
1653 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1654 break;
1655 case DRXK_POWER_DOWN_CORE:
1656 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1657 break;
1658 case DRXK_POWER_DOWN_PLL:
1659 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1660 break;
1661 case DRX_POWER_DOWN:
1662 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1663 break;
1664 default:
1665 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001666 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001667 }
1668
1669 /* If already in requested power mode, do nothing */
1670 if (state->m_currentPowerMode == *mode)
1671 return 0;
1672
1673 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001674 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001675 status = PowerUpDevice(state);
1676 if (status < 0)
1677 goto error;
1678 status = DVBTEnableOFDMTokenRing(state, true);
1679 if (status < 0)
1680 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001681 }
1682
1683 if (*mode == DRX_POWER_UP) {
1684 /* Restore analog & pin configuartion */
1685 } else {
1686 /* Power down to requested mode */
1687 /* Backup some register settings */
1688 /* Set pins with possible pull-ups connected
1689 to them in input mode */
1690 /* Analog power down */
1691 /* ADC power down */
1692 /* Power down device */
1693 /* stop all comm_exec */
1694 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001695 switch (state->m_OperationMode) {
1696 case OM_DVBT:
1697 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001698 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001699 goto error;
1700 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001701 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001702 goto error;
1703 break;
1704 case OM_QAM_ITU_A:
1705 case OM_QAM_ITU_C:
1706 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001707 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001708 goto error;
1709 status = PowerDownQAM(state);
1710 if (status < 0)
1711 goto error;
1712 break;
1713 default:
1714 break;
1715 }
1716 status = DVBTEnableOFDMTokenRing(state, false);
1717 if (status < 0)
1718 goto error;
1719 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1720 if (status < 0)
1721 goto error;
1722 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1723 if (status < 0)
1724 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001725
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001726 if (*mode != DRXK_POWER_DOWN_OFDM) {
1727 state->m_HICfgCtrl |=
1728 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1729 status = HI_CfgCommand(state);
1730 if (status < 0)
1731 goto error;
1732 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001733 }
1734 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001735
1736error:
1737 if (status < 0)
1738 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1739
Oliver Endrissebc7de22011-07-03 13:49:44 -03001740 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001741}
1742
1743static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1744{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001745 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001746 u16 cmdResult = 0;
1747 u16 data = 0;
1748 int status;
1749
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001750 dprintk(1, "\n");
1751
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001752 status = read16(state, SCU_COMM_EXEC__A, &data);
1753 if (status < 0)
1754 goto error;
1755 if (data == SCU_COMM_EXEC_ACTIVE) {
1756 /* Send OFDM stop command */
1757 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 -03001758 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001759 goto error;
1760 /* Send OFDM reset command */
1761 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1762 if (status < 0)
1763 goto error;
1764 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001765
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001766 /* Reset datapath for OFDM, processors first */
1767 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1768 if (status < 0)
1769 goto error;
1770 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1771 if (status < 0)
1772 goto error;
1773 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1774 if (status < 0)
1775 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001776
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001777 /* powerdown AFE */
1778 status = SetIqmAf(state, false);
1779 if (status < 0)
1780 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001781
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001782 /* powerdown to OFDM mode */
1783 if (setPowerMode) {
1784 status = CtrlPowerMode(state, &powerMode);
1785 if (status < 0)
1786 goto error;
1787 }
1788error:
1789 if (status < 0)
1790 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001791 return status;
1792}
1793
Oliver Endrissebc7de22011-07-03 13:49:44 -03001794static int SetOperationMode(struct drxk_state *state,
1795 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001796{
1797 int status = 0;
1798
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001799 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001800 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001801 Stop and power down previous standard
1802 TODO investigate total power down instead of partial
1803 power down depending on "previous" standard.
1804 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001805
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001806 /* disable HW lock indicator */
1807 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1808 if (status < 0)
1809 goto error;
1810
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001811 /* Device is already at the required mode */
1812 if (state->m_OperationMode == oMode)
1813 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001814
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001815 switch (state->m_OperationMode) {
1816 /* OM_NONE was added for start up */
1817 case OM_NONE:
1818 break;
1819 case OM_DVBT:
1820 status = MPEGTSStop(state);
1821 if (status < 0)
1822 goto error;
1823 status = PowerDownDVBT(state, true);
1824 if (status < 0)
1825 goto error;
1826 state->m_OperationMode = OM_NONE;
1827 break;
1828 case OM_QAM_ITU_A: /* fallthrough */
1829 case OM_QAM_ITU_C:
1830 status = MPEGTSStop(state);
1831 if (status < 0)
1832 goto error;
1833 status = PowerDownQAM(state);
1834 if (status < 0)
1835 goto error;
1836 state->m_OperationMode = OM_NONE;
1837 break;
1838 case OM_QAM_ITU_B:
1839 default:
1840 status = -EINVAL;
1841 goto error;
1842 }
1843
1844 /*
1845 Power up new standard
1846 */
1847 switch (oMode) {
1848 case OM_DVBT:
1849 state->m_OperationMode = oMode;
1850 status = SetDVBTStandard(state, oMode);
1851 if (status < 0)
1852 goto error;
1853 break;
1854 case OM_QAM_ITU_A: /* fallthrough */
1855 case OM_QAM_ITU_C:
1856 state->m_OperationMode = oMode;
1857 status = SetQAMStandard(state, oMode);
1858 if (status < 0)
1859 goto error;
1860 break;
1861 case OM_QAM_ITU_B:
1862 default:
1863 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001864 }
1865error:
1866 if (status < 0)
1867 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1868 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001869}
1870
1871static int Start(struct drxk_state *state, s32 offsetFreq,
1872 s32 IntermediateFrequency)
1873{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001874 int status = -EINVAL;
1875
1876 u16 IFreqkHz;
1877 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001878
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001879 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001880 if (state->m_DrxkState != DRXK_STOPPED &&
1881 state->m_DrxkState != DRXK_DTV_STARTED)
1882 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001883
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001884 state->m_bMirrorFreqSpect = (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001885
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001886 if (IntermediateFrequency < 0) {
1887 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1888 IntermediateFrequency = -IntermediateFrequency;
1889 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001890
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001891 switch (state->m_OperationMode) {
1892 case OM_QAM_ITU_A:
1893 case OM_QAM_ITU_C:
1894 IFreqkHz = (IntermediateFrequency / 1000);
1895 status = SetQAM(state, IFreqkHz, OffsetkHz);
1896 if (status < 0)
1897 goto error;
1898 state->m_DrxkState = DRXK_DTV_STARTED;
1899 break;
1900 case OM_DVBT:
1901 IFreqkHz = (IntermediateFrequency / 1000);
1902 status = MPEGTSStop(state);
1903 if (status < 0)
1904 goto error;
1905 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1906 if (status < 0)
1907 goto error;
1908 status = DVBTStart(state);
1909 if (status < 0)
1910 goto error;
1911 state->m_DrxkState = DRXK_DTV_STARTED;
1912 break;
1913 default:
1914 break;
1915 }
1916error:
1917 if (status < 0)
1918 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001919 return status;
1920}
1921
1922static int ShutDown(struct drxk_state *state)
1923{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001924 dprintk(1, "\n");
1925
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001926 MPEGTSStop(state);
1927 return 0;
1928}
1929
Oliver Endrissebc7de22011-07-03 13:49:44 -03001930static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1931 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001932{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001933 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001934
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001935 dprintk(1, "\n");
1936
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001937 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001938 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001939
1940 *pLockStatus = NOT_LOCKED;
1941
1942 /* define the SCU command code */
1943 switch (state->m_OperationMode) {
1944 case OM_QAM_ITU_A:
1945 case OM_QAM_ITU_B:
1946 case OM_QAM_ITU_C:
1947 status = GetQAMLockStatus(state, pLockStatus);
1948 break;
1949 case OM_DVBT:
1950 status = GetDVBTLockStatus(state, pLockStatus);
1951 break;
1952 default:
1953 break;
1954 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001955error:
1956 if (status < 0)
1957 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001958 return status;
1959}
1960
1961static int MPEGTSStart(struct drxk_state *state)
1962{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001963 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001964
1965 u16 fecOcSncMode = 0;
1966
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001967 /* Allow OC to sync again */
1968 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1969 if (status < 0)
1970 goto error;
1971 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1972 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1973 if (status < 0)
1974 goto error;
1975 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1976error:
1977 if (status < 0)
1978 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001979 return status;
1980}
1981
1982static int MPEGTSDtoInit(struct drxk_state *state)
1983{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001984 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001985
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001986 dprintk(1, "\n");
1987
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001988 /* Rate integration settings */
1989 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1990 if (status < 0)
1991 goto error;
1992 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1993 if (status < 0)
1994 goto error;
1995 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1996 if (status < 0)
1997 goto error;
1998 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1999 if (status < 0)
2000 goto error;
2001 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2002 if (status < 0)
2003 goto error;
2004 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2005 if (status < 0)
2006 goto error;
2007 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2008 if (status < 0)
2009 goto error;
2010 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2011 if (status < 0)
2012 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002013
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002014 /* Additional configuration */
2015 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2016 if (status < 0)
2017 goto error;
2018 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2019 if (status < 0)
2020 goto error;
2021 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2022error:
2023 if (status < 0)
2024 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2025
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002026 return status;
2027}
2028
Oliver Endrissebc7de22011-07-03 13:49:44 -03002029static int MPEGTSDtoSetup(struct drxk_state *state,
2030 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002031{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002032 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002033
Oliver Endrissebc7de22011-07-03 13:49:44 -03002034 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2035 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2036 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2037 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2038 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2039 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2040 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002041 u16 fecOcTmdMode = 0;
2042 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002043 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002044 bool staticCLK = false;
2045
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002046 dprintk(1, "\n");
2047
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002048 /* Check insertion of the Reed-Solomon parity bytes */
2049 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2050 if (status < 0)
2051 goto error;
2052 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2053 if (status < 0)
2054 goto error;
2055 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2056 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2057 if (state->m_insertRSByte == true) {
2058 /* enable parity symbol forward */
2059 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2060 /* MVAL disable during parity bytes */
2061 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2062 /* TS burst length to 204 */
2063 fecOcDtoBurstLen = 204;
2064 }
2065
2066 /* Check serial or parrallel output */
2067 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2068 if (state->m_enableParallel == false) {
2069 /* MPEG data output is serial -> set ipr_mode[0] */
2070 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2071 }
2072
2073 switch (oMode) {
2074 case OM_DVBT:
2075 maxBitRate = state->m_DVBTBitrate;
2076 fecOcTmdMode = 3;
2077 fecOcRcnCtlRate = 0xC00000;
2078 staticCLK = state->m_DVBTStaticCLK;
2079 break;
2080 case OM_QAM_ITU_A: /* fallthrough */
2081 case OM_QAM_ITU_C:
2082 fecOcTmdMode = 0x0004;
2083 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2084 maxBitRate = state->m_DVBCBitrate;
2085 staticCLK = state->m_DVBCStaticCLK;
2086 break;
2087 default:
2088 status = -EINVAL;
2089 } /* switch (standard) */
2090 if (status < 0)
2091 goto error;
2092
2093 /* Configure DTO's */
2094 if (staticCLK) {
2095 u32 bitRate = 0;
2096
2097 /* Rational DTO for MCLK source (static MCLK rate),
2098 Dynamic DTO for optimal grouping
2099 (avoid intra-packet gaps),
2100 DTO offset enable to sync TS burst with MSTRT */
2101 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2102 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2103 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2104 FEC_OC_FCT_MODE_VIRT_ENA__M);
2105
2106 /* Check user defined bitrate */
2107 bitRate = maxBitRate;
2108 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2109 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002110 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002111 /* Rational DTO period:
2112 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002113
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002114 Result should be floored,
2115 to make sure >= requested bitrate
2116 */
2117 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2118 * 1000) / bitRate);
2119 if (fecOcDtoPeriod <= 2)
2120 fecOcDtoPeriod = 0;
2121 else
2122 fecOcDtoPeriod -= 2;
2123 fecOcTmdIntUpdRate = 8;
2124 } else {
2125 /* (commonAttr->staticCLK == false) => dynamic mode */
2126 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2127 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2128 fecOcTmdIntUpdRate = 5;
2129 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002130
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002131 /* Write appropriate registers with requested configuration */
2132 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2133 if (status < 0)
2134 goto error;
2135 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2136 if (status < 0)
2137 goto error;
2138 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2139 if (status < 0)
2140 goto error;
2141 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2142 if (status < 0)
2143 goto error;
2144 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2145 if (status < 0)
2146 goto error;
2147 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2148 if (status < 0)
2149 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002150
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002151 /* Rate integration settings */
2152 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2153 if (status < 0)
2154 goto error;
2155 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2156 if (status < 0)
2157 goto error;
2158 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2159error:
2160 if (status < 0)
2161 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002162 return status;
2163}
2164
2165static int MPEGTSConfigurePolarity(struct drxk_state *state)
2166{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002167 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002168
2169 /* Data mask for the output data byte */
2170 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002171 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2172 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2173 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2174 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002175
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002176 dprintk(1, "\n");
2177
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002178 /* Control selective inversion of output bits */
2179 fecOcRegIprInvert &= (~(InvertDataMask));
2180 if (state->m_invertDATA == true)
2181 fecOcRegIprInvert |= InvertDataMask;
2182 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2183 if (state->m_invertERR == true)
2184 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2185 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2186 if (state->m_invertSTR == true)
2187 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2188 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2189 if (state->m_invertVAL == true)
2190 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2191 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2192 if (state->m_invertCLK == true)
2193 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002194
2195 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002196}
2197
2198#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2199
2200static int SetAgcRf(struct drxk_state *state,
2201 struct SCfgAgc *pAgcCfg, bool isDTV)
2202{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002203 int status = -EINVAL;
2204 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002205 struct SCfgAgc *pIfAgcSettings;
2206
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002207 dprintk(1, "\n");
2208
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002209 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002210 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002211
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002212 switch (pAgcCfg->ctrlMode) {
2213 case DRXK_AGC_CTRL_AUTO:
2214 /* Enable RF AGC DAC */
2215 status = read16(state, IQM_AF_STDBY__A, &data);
2216 if (status < 0)
2217 goto error;
2218 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2219 status = write16(state, IQM_AF_STDBY__A, data);
2220 if (status < 0)
2221 goto error;
2222 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2223 if (status < 0)
2224 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002225
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002226 /* Enable SCU RF AGC loop */
2227 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002228
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002229 /* Polarity */
2230 if (state->m_RfAgcPol)
2231 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2232 else
2233 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2234 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2235 if (status < 0)
2236 goto error;
2237
2238 /* Set speed (using complementary reduction value) */
2239 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2240 if (status < 0)
2241 goto error;
2242
2243 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2244 data |= (~(pAgcCfg->speed <<
2245 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2246 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2247
2248 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2249 if (status < 0)
2250 goto error;
2251
2252 if (IsDVBT(state))
2253 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2254 else if (IsQAM(state))
2255 pIfAgcSettings = &state->m_qamIfAgcCfg;
2256 else
2257 pIfAgcSettings = &state->m_atvIfAgcCfg;
2258 if (pIfAgcSettings == NULL) {
2259 status = -EINVAL;
2260 goto error;
2261 }
2262
2263 /* Set TOP, only if IF-AGC is in AUTO mode */
2264 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2265 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002266 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002267 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002268
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002269 /* Cut-Off current */
2270 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2271 if (status < 0)
2272 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002273
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002274 /* Max. output level */
2275 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2276 if (status < 0)
2277 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002278
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002279 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002280
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002281 case DRXK_AGC_CTRL_USER:
2282 /* Enable RF AGC DAC */
2283 status = read16(state, IQM_AF_STDBY__A, &data);
2284 if (status < 0)
2285 goto error;
2286 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2287 status = write16(state, IQM_AF_STDBY__A, data);
2288 if (status < 0)
2289 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002290
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002291 /* Disable SCU RF AGC loop */
2292 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2293 if (status < 0)
2294 goto error;
2295 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2296 if (state->m_RfAgcPol)
2297 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2298 else
2299 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2300 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2301 if (status < 0)
2302 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002303
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002304 /* SCU c.o.c. to 0, enabling full control range */
2305 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2306 if (status < 0)
2307 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002308
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002309 /* Write value to output pin */
2310 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2311 if (status < 0)
2312 goto error;
2313 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002314
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002315 case DRXK_AGC_CTRL_OFF:
2316 /* Disable RF AGC DAC */
2317 status = read16(state, IQM_AF_STDBY__A, &data);
2318 if (status < 0)
2319 goto error;
2320 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2321 status = write16(state, IQM_AF_STDBY__A, data);
2322 if (status < 0)
2323 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002324
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002325 /* Disable SCU RF AGC loop */
2326 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2327 if (status < 0)
2328 goto error;
2329 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2330 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2331 if (status < 0)
2332 goto error;
2333 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002334
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002335 default:
2336 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002337
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002338 }
2339error:
2340 if (status < 0)
2341 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002342 return status;
2343}
2344
2345#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2346
Oliver Endrissebc7de22011-07-03 13:49:44 -03002347static int SetAgcIf(struct drxk_state *state,
2348 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002349{
2350 u16 data = 0;
2351 int status = 0;
2352 struct SCfgAgc *pRfAgcSettings;
2353
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002354 dprintk(1, "\n");
2355
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002356 switch (pAgcCfg->ctrlMode) {
2357 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002358
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002359 /* Enable IF AGC DAC */
2360 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002361 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002362 goto error;
2363 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2364 status = write16(state, IQM_AF_STDBY__A, data);
2365 if (status < 0)
2366 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002367
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002368 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2369 if (status < 0)
2370 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002371
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002372 /* Enable SCU IF AGC loop */
2373 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2374
2375 /* Polarity */
2376 if (state->m_IfAgcPol)
2377 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2378 else
2379 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2380 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2381 if (status < 0)
2382 goto error;
2383
2384 /* Set speed (using complementary reduction value) */
2385 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2386 if (status < 0)
2387 goto error;
2388 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2389 data |= (~(pAgcCfg->speed <<
2390 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2391 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2392
2393 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2394 if (status < 0)
2395 goto error;
2396
2397 if (IsQAM(state))
2398 pRfAgcSettings = &state->m_qamRfAgcCfg;
2399 else
2400 pRfAgcSettings = &state->m_atvRfAgcCfg;
2401 if (pRfAgcSettings == NULL)
2402 return -1;
2403 /* Restore TOP */
2404 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2405 if (status < 0)
2406 goto error;
2407 break;
2408
2409 case DRXK_AGC_CTRL_USER:
2410
2411 /* Enable IF AGC DAC */
2412 status = read16(state, IQM_AF_STDBY__A, &data);
2413 if (status < 0)
2414 goto error;
2415 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2416 status = write16(state, IQM_AF_STDBY__A, data);
2417 if (status < 0)
2418 goto error;
2419
2420 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2421 if (status < 0)
2422 goto error;
2423
2424 /* Disable SCU IF AGC loop */
2425 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2426
2427 /* Polarity */
2428 if (state->m_IfAgcPol)
2429 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2430 else
2431 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2432 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2433 if (status < 0)
2434 goto error;
2435
2436 /* Write value to output pin */
2437 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2438 if (status < 0)
2439 goto error;
2440 break;
2441
2442 case DRXK_AGC_CTRL_OFF:
2443
2444 /* Disable If AGC DAC */
2445 status = read16(state, IQM_AF_STDBY__A, &data);
2446 if (status < 0)
2447 goto error;
2448 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2449 status = write16(state, IQM_AF_STDBY__A, data);
2450 if (status < 0)
2451 goto error;
2452
2453 /* Disable SCU IF AGC loop */
2454 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2455 if (status < 0)
2456 goto error;
2457 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2458 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2459 if (status < 0)
2460 goto error;
2461 break;
2462 } /* switch (agcSettingsIf->ctrlMode) */
2463
2464 /* always set the top to support
2465 configurations without if-loop */
2466 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2467error:
2468 if (status < 0)
2469 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002470 return status;
2471}
2472
2473static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2474{
2475 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002476 int status;
2477 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002478
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002479 dprintk(1, "\n");
2480
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002481 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2482 if (status < 0) {
2483 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2484 return status;
2485 }
2486
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002487 *pValue = 0;
2488
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002489 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2490 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2491 if (Level < 14000)
2492 *pValue = (14000 - Level) / 4;
2493 else
2494 *pValue = 0;
2495
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002496 return status;
2497}
2498
Oliver Endrissebc7de22011-07-03 13:49:44 -03002499static int GetQAMSignalToNoise(struct drxk_state *state,
2500 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002501{
2502 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002503 u16 qamSlErrPower = 0; /* accum. error between
2504 raw and sliced symbols */
2505 u32 qamSlSigPower = 0; /* used for MER, depends of
2506 QAM constellation */
2507 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002508
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002509 dprintk(1, "\n");
2510
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002511 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002512
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002513 /* get the register value needed for MER */
2514 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2515 if (status < 0) {
2516 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2517 return -EINVAL;
2518 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002519
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002520 switch (state->param.u.qam.modulation) {
2521 case QAM_16:
2522 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2523 break;
2524 case QAM_32:
2525 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2526 break;
2527 case QAM_64:
2528 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2529 break;
2530 case QAM_128:
2531 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2532 break;
2533 default:
2534 case QAM_256:
2535 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2536 break;
2537 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002538
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002539 if (qamSlErrPower > 0) {
2540 qamSlMer = Log10Times100(qamSlSigPower) -
2541 Log10Times100((u32) qamSlErrPower);
2542 }
2543 *pSignalToNoise = qamSlMer;
2544
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002545 return status;
2546}
2547
Oliver Endrissebc7de22011-07-03 13:49:44 -03002548static int GetDVBTSignalToNoise(struct drxk_state *state,
2549 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002550{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002551 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002552 u16 regData = 0;
2553 u32 EqRegTdSqrErrI = 0;
2554 u32 EqRegTdSqrErrQ = 0;
2555 u16 EqRegTdSqrErrExp = 0;
2556 u16 EqRegTdTpsPwrOfs = 0;
2557 u16 EqRegTdReqSmbCnt = 0;
2558 u32 tpsCnt = 0;
2559 u32 SqrErrIQ = 0;
2560 u32 a = 0;
2561 u32 b = 0;
2562 u32 c = 0;
2563 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002564 u16 transmissionParams = 0;
2565
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002566 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002567
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002568 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2569 if (status < 0)
2570 goto error;
2571 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2572 if (status < 0)
2573 goto error;
2574 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2575 if (status < 0)
2576 goto error;
2577 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2578 if (status < 0)
2579 goto error;
2580 /* Extend SQR_ERR_I operational range */
2581 EqRegTdSqrErrI = (u32) regData;
2582 if ((EqRegTdSqrErrExp > 11) &&
2583 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2584 EqRegTdSqrErrI += 0x00010000UL;
2585 }
2586 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2587 if (status < 0)
2588 goto error;
2589 /* Extend SQR_ERR_Q operational range */
2590 EqRegTdSqrErrQ = (u32) regData;
2591 if ((EqRegTdSqrErrExp > 11) &&
2592 (EqRegTdSqrErrQ < 0x00000FFFUL))
2593 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002594
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002595 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2596 if (status < 0)
2597 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002598
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002599 /* Check input data for MER */
2600
2601 /* MER calculation (in 0.1 dB) without math.h */
2602 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2603 iMER = 0;
2604 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2605 /* No error at all, this must be the HW reset value
2606 * Apparently no first measurement yet
2607 * Set MER to 0.0 */
2608 iMER = 0;
2609 } else {
2610 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2611 EqRegTdSqrErrExp;
2612 if ((transmissionParams &
2613 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2614 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2615 tpsCnt = 17;
2616 else
2617 tpsCnt = 68;
2618
2619 /* IMER = 100 * log10 (x)
2620 where x = (EqRegTdTpsPwrOfs^2 *
2621 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2622
2623 => IMER = a + b -c
2624 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2625 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2626 c = 100 * log10 (SqrErrIQ)
2627 */
2628
2629 /* log(x) x = 9bits * 9bits->18 bits */
2630 a = Log10Times100(EqRegTdTpsPwrOfs *
2631 EqRegTdTpsPwrOfs);
2632 /* log(x) x = 16bits * 7bits->23 bits */
2633 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2634 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2635 c = Log10Times100(SqrErrIQ);
2636
2637 iMER = a + b;
2638 /* No negative MER, clip to zero */
2639 if (iMER > c)
2640 iMER -= c;
2641 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002642 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002643 }
2644 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002645
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002646error:
2647 if (status < 0)
2648 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002649 return status;
2650}
2651
2652static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2653{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002654 dprintk(1, "\n");
2655
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002656 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002657 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002658 case OM_DVBT:
2659 return GetDVBTSignalToNoise(state, pSignalToNoise);
2660 case OM_QAM_ITU_A:
2661 case OM_QAM_ITU_C:
2662 return GetQAMSignalToNoise(state, pSignalToNoise);
2663 default:
2664 break;
2665 }
2666 return 0;
2667}
2668
2669#if 0
2670static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2671{
2672 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2673 int status = 0;
2674
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002675 dprintk(1, "\n");
2676
Oliver Endrissebc7de22011-07-03 13:49:44 -03002677 static s32 QE_SN[] = {
2678 51, /* QPSK 1/2 */
2679 69, /* QPSK 2/3 */
2680 79, /* QPSK 3/4 */
2681 89, /* QPSK 5/6 */
2682 97, /* QPSK 7/8 */
2683 108, /* 16-QAM 1/2 */
2684 131, /* 16-QAM 2/3 */
2685 146, /* 16-QAM 3/4 */
2686 156, /* 16-QAM 5/6 */
2687 160, /* 16-QAM 7/8 */
2688 165, /* 64-QAM 1/2 */
2689 187, /* 64-QAM 2/3 */
2690 202, /* 64-QAM 3/4 */
2691 216, /* 64-QAM 5/6 */
2692 225, /* 64-QAM 7/8 */
2693 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002694
2695 *pQuality = 0;
2696
2697 do {
2698 s32 SignalToNoise = 0;
2699 u16 Constellation = 0;
2700 u16 CodeRate = 0;
2701 u32 SignalToNoiseRel;
2702 u32 BERQuality;
2703
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002704 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2705 if (status < 0)
2706 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002707 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002708 if (status < 0)
2709 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002710 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2711
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002712 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002713 if (status < 0)
2714 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002715 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2716
2717 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2718 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2719 break;
2720 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002721 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002722 BERQuality = 100;
2723
Oliver Endrissebc7de22011-07-03 13:49:44 -03002724 if (SignalToNoiseRel < -70)
2725 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002726 else if (SignalToNoiseRel < 30)
2727 *pQuality = ((SignalToNoiseRel + 70) *
2728 BERQuality) / 100;
2729 else
2730 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002731 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002732 return 0;
2733};
2734
Oliver Endrissebc7de22011-07-03 13:49:44 -03002735static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002736{
2737 int status = 0;
2738 *pQuality = 0;
2739
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002740 dprintk(1, "\n");
2741
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002742 do {
2743 u32 SignalToNoise = 0;
2744 u32 BERQuality = 100;
2745 u32 SignalToNoiseRel = 0;
2746
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002747 status = GetQAMSignalToNoise(state, &SignalToNoise);
2748 if (status < 0)
2749 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002750
Oliver Endrissebc7de22011-07-03 13:49:44 -03002751 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002752 case QAM_16:
2753 SignalToNoiseRel = SignalToNoise - 200;
2754 break;
2755 case QAM_32:
2756 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002757 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002758 case QAM_64:
2759 SignalToNoiseRel = SignalToNoise - 260;
2760 break;
2761 case QAM_128:
2762 SignalToNoiseRel = SignalToNoise - 290;
2763 break;
2764 default:
2765 case QAM_256:
2766 SignalToNoiseRel = SignalToNoise - 320;
2767 break;
2768 }
2769
2770 if (SignalToNoiseRel < -70)
2771 *pQuality = 0;
2772 else if (SignalToNoiseRel < 30)
2773 *pQuality = ((SignalToNoiseRel + 70) *
2774 BERQuality) / 100;
2775 else
2776 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002777 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002778
2779 return status;
2780}
2781
2782static int GetQuality(struct drxk_state *state, s32 *pQuality)
2783{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002784 dprintk(1, "\n");
2785
Oliver Endrissebc7de22011-07-03 13:49:44 -03002786 switch (state->m_OperationMode) {
2787 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002788 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002789 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002790 return GetDVBCQuality(state, pQuality);
2791 default:
2792 break;
2793 }
2794
2795 return 0;
2796}
2797#endif
2798
2799/* Free data ram in SIO HI */
2800#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2801#define SIO_HI_RA_RAM_USR_END__A 0x420060
2802
2803#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2804#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2805#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2806#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2807
2808#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2809#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2810#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2811
2812static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2813{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002814 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002815
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002816 dprintk(1, "\n");
2817
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002818 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002819 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002820 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002821 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002822
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002823 if (state->no_i2c_bridge)
2824 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002825
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002826 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2827 if (status < 0)
2828 goto error;
2829 if (bEnableBridge) {
2830 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 -03002831 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002832 goto error;
2833 } else {
2834 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2835 if (status < 0)
2836 goto error;
2837 }
2838
2839 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2840
2841error:
2842 if (status < 0)
2843 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002844 return status;
2845}
2846
Oliver Endrissebc7de22011-07-03 13:49:44 -03002847static int SetPreSaw(struct drxk_state *state,
2848 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002849{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002850 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002851
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002852 dprintk(1, "\n");
2853
Oliver Endrissebc7de22011-07-03 13:49:44 -03002854 if ((pPreSawCfg == NULL)
2855 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002856 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002857
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002858 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002859error:
2860 if (status < 0)
2861 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002862 return status;
2863}
2864
2865static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002866 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002867{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002868 u16 blStatus = 0;
2869 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2870 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2871 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002872 unsigned long end;
2873
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002874 dprintk(1, "\n");
2875
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002876 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002877 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2878 if (status < 0)
2879 goto error;
2880 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2881 if (status < 0)
2882 goto error;
2883 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2884 if (status < 0)
2885 goto error;
2886 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2887 if (status < 0)
2888 goto error;
2889 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2890 if (status < 0)
2891 goto error;
2892 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2893 if (status < 0)
2894 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002895
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002896 end = jiffies + msecs_to_jiffies(timeOut);
2897 do {
2898 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2899 if (status < 0)
2900 goto error;
2901 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2902 if (blStatus == 0x1) {
2903 printk(KERN_ERR "drxk: SIO not ready\n");
2904 status = -EINVAL;
2905 goto error2;
2906 }
2907error:
2908 if (status < 0)
2909 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2910error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002911 mutex_unlock(&state->mutex);
2912 return status;
2913
2914}
2915
Oliver Endrissebc7de22011-07-03 13:49:44 -03002916static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002917{
2918 u16 data = 0;
2919 int status;
2920
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002921 dprintk(1, "\n");
2922
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002923 /* Start measurement */
2924 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2925 if (status < 0)
2926 goto error;
2927 status = write16(state, IQM_AF_START_LOCK__A, 1);
2928 if (status < 0)
2929 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002930
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002931 *count = 0;
2932 status = read16(state, IQM_AF_PHASE0__A, &data);
2933 if (status < 0)
2934 goto error;
2935 if (data == 127)
2936 *count = *count + 1;
2937 status = read16(state, IQM_AF_PHASE1__A, &data);
2938 if (status < 0)
2939 goto error;
2940 if (data == 127)
2941 *count = *count + 1;
2942 status = read16(state, IQM_AF_PHASE2__A, &data);
2943 if (status < 0)
2944 goto error;
2945 if (data == 127)
2946 *count = *count + 1;
2947
2948error:
2949 if (status < 0)
2950 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002951 return status;
2952}
2953
2954static int ADCSynchronization(struct drxk_state *state)
2955{
2956 u16 count = 0;
2957 int status;
2958
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002959 dprintk(1, "\n");
2960
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002961 status = ADCSyncMeasurement(state, &count);
2962 if (status < 0)
2963 goto error;
2964
2965 if (count == 1) {
2966 /* Try sampling on a diffrent edge */
2967 u16 clkNeg = 0;
2968
2969 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2970 if (status < 0)
2971 goto error;
2972 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2973 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2974 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2975 clkNeg |=
2976 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2977 } else {
2978 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2979 clkNeg |=
2980 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2981 }
2982 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2983 if (status < 0)
2984 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002985 status = ADCSyncMeasurement(state, &count);
2986 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002987 goto error;
2988 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002989
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002990 if (count < 2)
2991 status = -EINVAL;
2992error:
2993 if (status < 0)
2994 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002995 return status;
2996}
2997
2998static int SetFrequencyShifter(struct drxk_state *state,
2999 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003000 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003001{
3002 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003003 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003004 u32 fmFrequencyShift = 0;
3005 bool tunerMirror = !state->m_bMirrorFreqSpect;
3006 u32 adcFreq;
3007 bool adcFlip;
3008 int status;
3009 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003010 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003011 u32 frequencyShift;
3012 bool imageToSelect;
3013
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003014 dprintk(1, "\n");
3015
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003016 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003017 Program frequency shifter
3018 No need to account for mirroring on RF
3019 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003020 if (isDTV) {
3021 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3022 (state->m_OperationMode == OM_QAM_ITU_C) ||
3023 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003024 selectPosImage = true;
3025 else
3026 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003027 }
3028 if (tunerMirror)
3029 /* tuner doesn't mirror */
3030 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003031 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003032 else
3033 /* tuner mirrors */
3034 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003035 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003036 if (ifFreqActual > samplingFrequency / 2) {
3037 /* adc mirrors */
3038 adcFreq = samplingFrequency - ifFreqActual;
3039 adcFlip = true;
3040 } else {
3041 /* adc doesn't mirror */
3042 adcFreq = ifFreqActual;
3043 adcFlip = false;
3044 }
3045
3046 frequencyShift = adcFreq;
3047 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003048 adcFlip ^ selectPosImage;
3049 state->m_IqmFsRateOfs =
3050 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003051
3052 if (imageToSelect)
3053 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3054
3055 /* Program frequency shifter with tuner offset compensation */
3056 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003057 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3058 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003059 if (status < 0)
3060 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003061 return status;
3062}
3063
3064static int InitAGC(struct drxk_state *state, bool isDTV)
3065{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003066 u16 ingainTgt = 0;
3067 u16 ingainTgtMin = 0;
3068 u16 ingainTgtMax = 0;
3069 u16 clpCyclen = 0;
3070 u16 clpSumMin = 0;
3071 u16 clpDirTo = 0;
3072 u16 snsSumMin = 0;
3073 u16 snsSumMax = 0;
3074 u16 clpSumMax = 0;
3075 u16 snsDirTo = 0;
3076 u16 kiInnergainMin = 0;
3077 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003078 u16 ifIaccuHiTgtMin = 0;
3079 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003080 u16 data = 0;
3081 u16 fastClpCtrlDelay = 0;
3082 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003083 int status = 0;
3084
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003085 dprintk(1, "\n");
3086
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003087 /* Common settings */
3088 snsSumMax = 1023;
3089 ifIaccuHiTgtMin = 2047;
3090 clpCyclen = 500;
3091 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003092
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003093 /* AGCInit() not available for DVBT; init done in microcode */
3094 if (!IsQAM(state)) {
3095 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3096 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003097 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003098
3099 /* FIXME: Analog TV AGC require different settings */
3100
3101 /* Standard specific settings */
3102 clpSumMin = 8;
3103 clpDirTo = (u16) -9;
3104 clpCtrlMode = 0;
3105 snsSumMin = 8;
3106 snsDirTo = (u16) -9;
3107 kiInnergainMin = (u16) -1030;
3108 ifIaccuHiTgtMax = 0x2380;
3109 ifIaccuHiTgt = 0x2380;
3110 ingainTgtMin = 0x0511;
3111 ingainTgt = 0x0511;
3112 ingainTgtMax = 5119;
3113 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3114
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003115 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3116 if (status < 0)
3117 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003118
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003119 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3120 if (status < 0)
3121 goto error;
3122 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3123 if (status < 0)
3124 goto error;
3125 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3126 if (status < 0)
3127 goto error;
3128 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3129 if (status < 0)
3130 goto error;
3131 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3132 if (status < 0)
3133 goto error;
3134 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3135 if (status < 0)
3136 goto error;
3137 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3138 if (status < 0)
3139 goto error;
3140 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3141 if (status < 0)
3142 goto error;
3143 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3144 if (status < 0)
3145 goto error;
3146 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3147 if (status < 0)
3148 goto error;
3149 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3150 if (status < 0)
3151 goto error;
3152 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3153 if (status < 0)
3154 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003155
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003156 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3157 if (status < 0)
3158 goto error;
3159 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3160 if (status < 0)
3161 goto error;
3162 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3163 if (status < 0)
3164 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003165
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003166 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3167 if (status < 0)
3168 goto error;
3169 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3170 if (status < 0)
3171 goto error;
3172 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3173 if (status < 0)
3174 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003175
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003176 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3177 if (status < 0)
3178 goto error;
3179 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3180 if (status < 0)
3181 goto error;
3182 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3183 if (status < 0)
3184 goto error;
3185 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3186 if (status < 0)
3187 goto error;
3188 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3189 if (status < 0)
3190 goto error;
3191 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3192 if (status < 0)
3193 goto error;
3194 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3195 if (status < 0)
3196 goto error;
3197 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3198 if (status < 0)
3199 goto error;
3200 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3201 if (status < 0)
3202 goto error;
3203 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3204 if (status < 0)
3205 goto error;
3206 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3207 if (status < 0)
3208 goto error;
3209 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3210 if (status < 0)
3211 goto error;
3212 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3213 if (status < 0)
3214 goto error;
3215 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3216 if (status < 0)
3217 goto error;
3218 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3219 if (status < 0)
3220 goto error;
3221 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3222 if (status < 0)
3223 goto error;
3224 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3225 if (status < 0)
3226 goto error;
3227 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3228 if (status < 0)
3229 goto error;
3230 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3231 if (status < 0)
3232 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003233
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003234 /* Initialize inner-loop KI gain factors */
3235 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3236 if (status < 0)
3237 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003238
3239 data = 0x0657;
3240 data &= ~SCU_RAM_AGC_KI_RF__M;
3241 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3242 data &= ~SCU_RAM_AGC_KI_IF__M;
3243 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3244
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003245 status = write16(state, SCU_RAM_AGC_KI__A, data);
3246error:
3247 if (status < 0)
3248 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003249 return status;
3250}
3251
Oliver Endrissebc7de22011-07-03 13:49:44 -03003252static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003253{
3254 int status;
3255
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003256 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003257 if (packetErr == NULL)
3258 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3259 else
3260 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3261 if (status < 0)
3262 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003263 return status;
3264}
3265
3266static int DVBTScCommand(struct drxk_state *state,
3267 u16 cmd, u16 subcmd,
3268 u16 param0, u16 param1, u16 param2,
3269 u16 param3, u16 param4)
3270{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003271 u16 curCmd = 0;
3272 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003273 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003274 u16 scExec = 0;
3275 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003276
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003277 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003278 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003279 if (scExec != 1) {
3280 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003281 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003282 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003283 if (status < 0)
3284 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003285
3286 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003287 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003288 do {
3289 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003290 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003291 retryCnt++;
3292 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003293 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3294 goto error;
3295
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003296 /* Write sub-command */
3297 switch (cmd) {
3298 /* All commands using sub-cmd */
3299 case OFDM_SC_RA_RAM_CMD_PROC_START:
3300 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3301 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003302 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3303 if (status < 0)
3304 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003305 break;
3306 default:
3307 /* Do nothing */
3308 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003309 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003310
3311 /* Write needed parameters and the command */
3312 switch (cmd) {
3313 /* All commands using 5 parameters */
3314 /* All commands using 4 parameters */
3315 /* All commands using 3 parameters */
3316 /* All commands using 2 parameters */
3317 case OFDM_SC_RA_RAM_CMD_PROC_START:
3318 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3319 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003320 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003321 /* All commands using 1 parameters */
3322 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3323 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003324 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003325 /* All commands using 0 parameters */
3326 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3327 case OFDM_SC_RA_RAM_CMD_NULL:
3328 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003329 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003330 break;
3331 default:
3332 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003333 status = -EINVAL;
3334 }
3335 if (status < 0)
3336 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003337
3338 /* Wait until sc is ready processing command */
3339 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003340 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003341 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003342 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003343 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003344 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003345 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3346 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003347
3348 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003349 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003350 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003351 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003352 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003353 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003354 if (status < 0)
3355 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003356
3357 /* Retreive results parameters from SC */
3358 switch (cmd) {
3359 /* All commands yielding 5 results */
3360 /* All commands yielding 4 results */
3361 /* All commands yielding 3 results */
3362 /* All commands yielding 2 results */
3363 /* All commands yielding 1 result */
3364 case OFDM_SC_RA_RAM_CMD_USER_IO:
3365 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003366 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003367 /* All commands yielding 0 results */
3368 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3369 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3370 case OFDM_SC_RA_RAM_CMD_PROC_START:
3371 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3372 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3373 case OFDM_SC_RA_RAM_CMD_NULL:
3374 break;
3375 default:
3376 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003377 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003378 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003379 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003380error:
3381 if (status < 0)
3382 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003383 return status;
3384}
3385
Oliver Endrissebc7de22011-07-03 13:49:44 -03003386static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003387{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003388 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003389 int status;
3390
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003391 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003392 status = CtrlPowerMode(state, &powerMode);
3393 if (status < 0)
3394 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003395 return status;
3396}
3397
Oliver Endrissebc7de22011-07-03 13:49:44 -03003398static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003399{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003400 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003401
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003402 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003403 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003404 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003405 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003406 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003407 if (status < 0)
3408 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003409 return status;
3410}
3411
3412#define DEFAULT_FR_THRES_8K 4000
3413static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3414{
3415
3416 int status;
3417
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003418 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003419 if (*enabled == true) {
3420 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003421 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003422 DEFAULT_FR_THRES_8K);
3423 } else {
3424 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003425 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003426 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003427 if (status < 0)
3428 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003429
3430 return status;
3431}
3432
3433static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3434 struct DRXKCfgDvbtEchoThres_t *echoThres)
3435{
3436 u16 data = 0;
3437 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003438
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003439 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003440 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3441 if (status < 0)
3442 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003443
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003444 switch (echoThres->fftMode) {
3445 case DRX_FFTMODE_2K:
3446 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3447 data |= ((echoThres->threshold <<
3448 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3449 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003450 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003451 case DRX_FFTMODE_8K:
3452 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3453 data |= ((echoThres->threshold <<
3454 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3455 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003456 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003457 default:
3458 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003459 }
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;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003823 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003824 case TRANSMISSION_MODE_2K:
3825 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003826 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003827 }
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;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003837 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003838 case GUARD_INTERVAL_1_32:
3839 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003840 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003841 case GUARD_INTERVAL_1_16:
3842 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003843 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003844 case GUARD_INTERVAL_1_8:
3845 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003846 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003847 }
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;
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005386 u16 setEnvParameters[5] = { 0, 0, 0, 0, 0 };
Oliver Endrissebc7de22011-07-03 13:49:44 -03005387 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);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005453 if (status < 0) {
5454 /* Fall-back to the simpler call */
5455 setParamParameters[0] = QAM_TOP_ANNEX_A;
5456 if (state->m_OperationMode == OM_QAM_ITU_C)
5457 setEnvParameters[0] = QAM_TOP_ANNEX_C; /* Annex */
5458 else
5459 setEnvParameters[0] = 0;
5460
5461 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setEnvParameters, 1, &cmdResult);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005462 if (status < 0)
5463 goto error;
5464
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005465 setParamParameters[0] = state->m_Constellation; /* constellation */
5466 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5467
5468 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
5469 }
5470 if (status < 0)
5471 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005472
5473 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5474 setup constellation independent registers */
5475#if 0
5476 status = SetFrequency(channel, tunerFreqOffset));
5477 if (status < 0)
5478 goto error;
5479#endif
5480 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5481 if (status < 0)
5482 goto error;
5483
5484 /* Setup BER measurement */
5485 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5486 if (status < 0)
5487 goto error;
5488
5489 /* Reset default values */
5490 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5491 if (status < 0)
5492 goto error;
5493 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5494 if (status < 0)
5495 goto error;
5496
5497 /* Reset default LC values */
5498 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5499 if (status < 0)
5500 goto error;
5501 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5502 if (status < 0)
5503 goto error;
5504 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5505 if (status < 0)
5506 goto error;
5507 status = write16(state, QAM_LC_MODE__A, 7);
5508 if (status < 0)
5509 goto error;
5510
5511 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5512 if (status < 0)
5513 goto error;
5514 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5515 if (status < 0)
5516 goto error;
5517 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5518 if (status < 0)
5519 goto error;
5520 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5521 if (status < 0)
5522 goto error;
5523 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5524 if (status < 0)
5525 goto error;
5526 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5527 if (status < 0)
5528 goto error;
5529 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5530 if (status < 0)
5531 goto error;
5532 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5533 if (status < 0)
5534 goto error;
5535 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5536 if (status < 0)
5537 goto error;
5538 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5539 if (status < 0)
5540 goto error;
5541 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5542 if (status < 0)
5543 goto error;
5544 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5545 if (status < 0)
5546 goto error;
5547 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5548 if (status < 0)
5549 goto error;
5550 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5551 if (status < 0)
5552 goto error;
5553 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5554 if (status < 0)
5555 goto error;
5556
5557 /* Mirroring, QAM-block starting point not inverted */
5558 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5559 if (status < 0)
5560 goto error;
5561
5562 /* Halt SCU to enable safe non-atomic accesses */
5563 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5564 if (status < 0)
5565 goto error;
5566
5567 /* STEP 4: constellation specific setup */
5568 switch (state->param.u.qam.modulation) {
5569 case QAM_16:
5570 status = SetQAM16(state);
5571 break;
5572 case QAM_32:
5573 status = SetQAM32(state);
5574 break;
5575 case QAM_AUTO:
5576 case QAM_64:
5577 status = SetQAM64(state);
5578 break;
5579 case QAM_128:
5580 status = SetQAM128(state);
5581 break;
5582 case QAM_256:
5583 status = SetQAM256(state);
5584 break;
5585 default:
5586 status = -EINVAL;
5587 break;
5588 }
5589 if (status < 0)
5590 goto error;
5591
5592 /* Activate SCU to enable SCU commands */
5593 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5594 if (status < 0)
5595 goto error;
5596
5597 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5598 /* extAttr->currentChannel.constellation = channel->constellation; */
5599 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5600 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5601 if (status < 0)
5602 goto error;
5603
5604 /* Start processes */
5605 status = MPEGTSStart(state);
5606 if (status < 0)
5607 goto error;
5608 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5609 if (status < 0)
5610 goto error;
5611 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5612 if (status < 0)
5613 goto error;
5614 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5615 if (status < 0)
5616 goto error;
5617
5618 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5619 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5620 if (status < 0)
5621 goto error;
5622
5623 /* update global DRXK data container */
5624/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5625
5626error:
5627 if (status < 0)
5628 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005629 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005630}
5631
Oliver Endrissebc7de22011-07-03 13:49:44 -03005632static int SetQAMStandard(struct drxk_state *state,
5633 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005634{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005635 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005636#ifdef DRXK_QAM_TAPS
5637#define DRXK_QAMA_TAPS_SELECT
5638#include "drxk_filters.h"
5639#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005640#endif
5641
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005642 dprintk(1, "\n");
5643
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005644 /* added antenna switch */
5645 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005646
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005647 /* Ensure correct power-up mode */
5648 status = PowerUpQAM(state);
5649 if (status < 0)
5650 goto error;
5651 /* Reset QAM block */
5652 status = QAMResetQAM(state);
5653 if (status < 0)
5654 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005655
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005656 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005657
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005658 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5659 if (status < 0)
5660 goto error;
5661 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5662 if (status < 0)
5663 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005664
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005665 /* Upload IQM Channel Filter settings by
5666 boot loader from ROM table */
5667 switch (oMode) {
5668 case OM_QAM_ITU_A:
5669 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5670 break;
5671 case OM_QAM_ITU_C:
5672 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 -03005673 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005674 goto error;
5675 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5676 break;
5677 default:
5678 status = -EINVAL;
5679 }
5680 if (status < 0)
5681 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005682
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005683 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5684 if (status < 0)
5685 goto error;
5686 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5687 if (status < 0)
5688 goto error;
5689 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5690 if (status < 0)
5691 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005692
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005693 status = write16(state, IQM_RC_STRETCH__A, 21);
5694 if (status < 0)
5695 goto error;
5696 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5697 if (status < 0)
5698 goto error;
5699 status = write16(state, IQM_AF_CLP_TH__A, 448);
5700 if (status < 0)
5701 goto error;
5702 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5703 if (status < 0)
5704 goto error;
5705 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5706 if (status < 0)
5707 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005708
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005709 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5710 if (status < 0)
5711 goto error;
5712 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5713 if (status < 0)
5714 goto error;
5715 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5716 if (status < 0)
5717 goto error;
5718 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5719 if (status < 0)
5720 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005721
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005722 /* IQM Impulse Noise Processing Unit */
5723 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5724 if (status < 0)
5725 goto error;
5726 status = write16(state, IQM_CF_DATATH__A, 1000);
5727 if (status < 0)
5728 goto error;
5729 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5730 if (status < 0)
5731 goto error;
5732 status = write16(state, IQM_CF_DET_LCT__A, 0);
5733 if (status < 0)
5734 goto error;
5735 status = write16(state, IQM_CF_WND_LEN__A, 1);
5736 if (status < 0)
5737 goto error;
5738 status = write16(state, IQM_CF_PKDTH__A, 1);
5739 if (status < 0)
5740 goto error;
5741 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5742 if (status < 0)
5743 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005744
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005745 /* turn on IQMAF. Must be done before setAgc**() */
5746 status = SetIqmAf(state, true);
5747 if (status < 0)
5748 goto error;
5749 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5750 if (status < 0)
5751 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005752
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005753 /* IQM will not be reset from here, sync ADC and update/init AGC */
5754 status = ADCSynchronization(state);
5755 if (status < 0)
5756 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005757
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005758 /* Set the FSM step period */
5759 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5760 if (status < 0)
5761 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005762
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005763 /* Halt SCU to enable safe non-atomic accesses */
5764 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5765 if (status < 0)
5766 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005767
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005768 /* No more resets of the IQM, current standard correctly set =>
5769 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005770
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005771 status = InitAGC(state, true);
5772 if (status < 0)
5773 goto error;
5774 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5775 if (status < 0)
5776 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005777
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005778 /* Configure AGC's */
5779 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5780 if (status < 0)
5781 goto error;
5782 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5783 if (status < 0)
5784 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005785
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005786 /* Activate SCU to enable SCU commands */
5787 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5788error:
5789 if (status < 0)
5790 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005791 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005792}
5793
5794static int WriteGPIO(struct drxk_state *state)
5795{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005796 int status;
5797 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005798
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005799 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005800 /* stop lock indicator process */
5801 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5802 if (status < 0)
5803 goto error;
5804
5805 /* Write magic word to enable pdr reg write */
5806 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5807 if (status < 0)
5808 goto error;
5809
5810 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005811 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5812 /* write to io pad configuration register - output mode */
5813 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5814 if (status < 0)
5815 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005816
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005817 /* use corresponding bit in io data output registar */
5818 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5819 if (status < 0)
5820 goto error;
5821 if ((state->m_GPIO & 0x0001) == 0)
5822 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5823 else
5824 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5825 /* write back to io data output register */
5826 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5827 if (status < 0)
5828 goto error;
5829 }
5830 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5831 /* write to io pad configuration register - output mode */
5832 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5833 if (status < 0)
5834 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005835
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005836 /* use corresponding bit in io data output registar */
5837 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5838 if (status < 0)
5839 goto error;
5840 if ((state->m_GPIO & 0x0002) == 0)
5841 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5842 else
5843 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5844 /* write back to io data output register */
5845 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5846 if (status < 0)
5847 goto error;
5848 }
5849 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5850 /* write to io pad configuration register - output mode */
5851 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5852 if (status < 0)
5853 goto error;
5854
5855 /* use corresponding bit in io data output registar */
5856 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5857 if (status < 0)
5858 goto error;
5859 if ((state->m_GPIO & 0x0004) == 0)
5860 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5861 else
5862 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5863 /* write back to io data output register */
5864 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5865 if (status < 0)
5866 goto error;
5867 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005868 }
5869 /* Write magic word to disable pdr reg write */
5870 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5871error:
5872 if (status < 0)
5873 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005874 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005875}
5876
5877static int SwitchAntennaToQAM(struct drxk_state *state)
5878{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005879 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005880 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005881
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005882 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005883
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005884 if (!state->antenna_gpio)
5885 return 0;
5886
5887 gpio_state = state->m_GPIO & state->antenna_gpio;
5888
5889 if (state->antenna_dvbt ^ gpio_state) {
5890 /* Antenna is on DVB-T mode. Switch */
5891 if (state->antenna_dvbt)
5892 state->m_GPIO &= ~state->antenna_gpio;
5893 else
5894 state->m_GPIO |= state->antenna_gpio;
5895 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005896 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005897 if (status < 0)
5898 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005899 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005900}
5901
5902static int SwitchAntennaToDVBT(struct drxk_state *state)
5903{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005904 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005905 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005906
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005907 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005908
5909 if (!state->antenna_gpio)
5910 return 0;
5911
5912 gpio_state = state->m_GPIO & state->antenna_gpio;
5913
5914 if (!(state->antenna_dvbt ^ gpio_state)) {
5915 /* Antenna is on DVB-C mode. Switch */
5916 if (state->antenna_dvbt)
5917 state->m_GPIO |= state->antenna_gpio;
5918 else
5919 state->m_GPIO &= ~state->antenna_gpio;
5920 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005921 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005922 if (status < 0)
5923 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005924 return status;
5925}
5926
5927
5928static int PowerDownDevice(struct drxk_state *state)
5929{
5930 /* Power down to requested mode */
5931 /* Backup some register settings */
5932 /* Set pins with possible pull-ups connected to them in input mode */
5933 /* Analog power down */
5934 /* ADC power down */
5935 /* Power down device */
5936 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005937
5938 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005939 if (state->m_bPDownOpenBridge) {
5940 /* Open I2C bridge before power down of DRXK */
5941 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005942 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005943 goto error;
5944 }
5945 /* driver 0.9.0 */
5946 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005947 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005948 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005949
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005950 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5951 if (status < 0)
5952 goto error;
5953 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5954 if (status < 0)
5955 goto error;
5956 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5957 status = HI_CfgCommand(state);
5958error:
5959 if (status < 0)
5960 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5961
5962 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005963}
5964
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005965static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005966{
5967 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005968 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005969
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005970 dprintk(1, "\n");
5971
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005972 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5973 if (err < 0) {
5974 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005975 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005976 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005977 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005978 return err;
5979 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005980 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005981 release_firmware(fw);
5982 return err;
5983}
5984
5985static int init_drxk(struct drxk_state *state)
5986{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005987 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005988 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005989 u16 driverVersion;
5990
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005991 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005992 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005993 status = PowerUpDevice(state);
5994 if (status < 0)
5995 goto error;
5996 status = DRXX_Open(state);
5997 if (status < 0)
5998 goto error;
5999 /* Soft reset of OFDM-, sys- and osc-clockdomain */
6000 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);
6001 if (status < 0)
6002 goto error;
6003 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6004 if (status < 0)
6005 goto error;
6006 /* TODO is this needed, if yes how much delay in worst case scenario */
6007 msleep(1);
6008 state->m_DRXK_A3_PATCH_CODE = true;
6009 status = GetDeviceCapabilities(state);
6010 if (status < 0)
6011 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006012
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006013 /* Bridge delay, uses oscilator clock */
6014 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6015 /* SDA brdige delay */
6016 state->m_HICfgBridgeDelay =
6017 (u16) ((state->m_oscClockFreq / 1000) *
6018 HI_I2C_BRIDGE_DELAY) / 1000;
6019 /* Clipping */
6020 if (state->m_HICfgBridgeDelay >
6021 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006022 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006023 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6024 }
6025 /* SCL bridge delay, same as SDA for now */
6026 state->m_HICfgBridgeDelay +=
6027 state->m_HICfgBridgeDelay <<
6028 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006029
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006030 status = InitHI(state);
6031 if (status < 0)
6032 goto error;
6033 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006034#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006035 if (!(state->m_DRXK_A1_ROM_CODE)
6036 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006037#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006038 {
6039 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6040 if (status < 0)
6041 goto error;
6042 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006043
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006044 /* disable MPEG port */
6045 status = MPEGTSDisable(state);
6046 if (status < 0)
6047 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006048
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006049 /* Stop AUD and SCU */
6050 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6051 if (status < 0)
6052 goto error;
6053 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6054 if (status < 0)
6055 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006056
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006057 /* enable token-ring bus through OFDM block for possible ucode upload */
6058 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6059 if (status < 0)
6060 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006061
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006062 /* include boot loader section */
6063 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6064 if (status < 0)
6065 goto error;
6066 status = BLChainCmd(state, 0, 6, 100);
6067 if (status < 0)
6068 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006069
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006070 if (!state->microcode_name)
6071 load_microcode(state, "drxk_a3.mc");
6072 else
6073 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006074
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006075 /* disable token-ring bus through OFDM block for possible ucode upload */
6076 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6077 if (status < 0)
6078 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006079
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006080 /* Run SCU for a little while to initialize microcode version numbers */
6081 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6082 if (status < 0)
6083 goto error;
6084 status = DRXX_Open(state);
6085 if (status < 0)
6086 goto error;
6087 /* added for test */
6088 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006089
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006090 powerMode = DRXK_POWER_DOWN_OFDM;
6091 status = CtrlPowerMode(state, &powerMode);
6092 if (status < 0)
6093 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006094
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006095 /* Stamp driver version number in SCU data RAM in BCD code
6096 Done to enable field application engineers to retreive drxdriver version
6097 via I2C from SCU RAM.
6098 Not using SCU command interface for SCU register access since no
6099 microcode may be present.
6100 */
6101 driverVersion =
6102 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6103 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6104 ((DRXK_VERSION_MAJOR % 10) << 4) +
6105 (DRXK_VERSION_MINOR % 10);
6106 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6107 if (status < 0)
6108 goto error;
6109 driverVersion =
6110 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6111 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6112 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6113 (DRXK_VERSION_PATCH % 10);
6114 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6115 if (status < 0)
6116 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006117
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006118 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6119 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6120 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006121
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006122 /* Dirty fix of default values for ROM/PATCH microcode
6123 Dirty because this fix makes it impossible to setup suitable values
6124 before calling DRX_Open. This solution requires changes to RF AGC speed
6125 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006126
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006127 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006128
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006129 /* Reset driver debug flags to 0 */
6130 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6131 if (status < 0)
6132 goto error;
6133 /* driver 0.9.0 */
6134 /* Setup FEC OC:
6135 NOTE: No more full FEC resets allowed afterwards!! */
6136 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6137 if (status < 0)
6138 goto error;
6139 /* MPEGTS functions are still the same */
6140 status = MPEGTSDtoInit(state);
6141 if (status < 0)
6142 goto error;
6143 status = MPEGTSStop(state);
6144 if (status < 0)
6145 goto error;
6146 status = MPEGTSConfigurePolarity(state);
6147 if (status < 0)
6148 goto error;
6149 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6150 if (status < 0)
6151 goto error;
6152 /* added: configure GPIO */
6153 status = WriteGPIO(state);
6154 if (status < 0)
6155 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006156
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006157 state->m_DrxkState = DRXK_STOPPED;
6158
6159 if (state->m_bPowerDown) {
6160 status = PowerDownDevice(state);
6161 if (status < 0)
6162 goto error;
6163 state->m_DrxkState = DRXK_POWERED_DOWN;
6164 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006165 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006166 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006167error:
6168 if (status < 0)
6169 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006170
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006171 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006172}
6173
Oliver Endrissebc7de22011-07-03 13:49:44 -03006174static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006175{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006176 struct drxk_state *state = fe->demodulator_priv;
6177
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006178 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006179 kfree(state);
6180}
6181
Oliver Endrissebc7de22011-07-03 13:49:44 -03006182static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006183{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006184 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006185
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006186 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006187 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006188 return -EBUSY;
6189 SetOperationMode(state, OM_QAM_ITU_A);
6190 return 0;
6191}
6192
Oliver Endrissebc7de22011-07-03 13:49:44 -03006193static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006194{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006195 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006196
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006197 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006198 ShutDown(state);
6199 mutex_unlock(&state->ctlock);
6200 return 0;
6201}
6202
Oliver Endrissebc7de22011-07-03 13:49:44 -03006203static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006204{
6205 struct drxk_state *state = fe->demodulator_priv;
6206
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006207 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006208 return ConfigureI2CBridge(state, enable ? true : false);
6209}
6210
Oliver Endrissebc7de22011-07-03 13:49:44 -03006211static int drxk_set_parameters(struct dvb_frontend *fe,
6212 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006213{
6214 struct drxk_state *state = fe->demodulator_priv;
6215 u32 IF;
6216
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006217 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006218 if (fe->ops.i2c_gate_ctrl)
6219 fe->ops.i2c_gate_ctrl(fe, 1);
6220 if (fe->ops.tuner_ops.set_params)
6221 fe->ops.tuner_ops.set_params(fe, p);
6222 if (fe->ops.i2c_gate_ctrl)
6223 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006224 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006225 fe->ops.tuner_ops.get_frequency(fe, &IF);
6226 Start(state, 0, IF);
6227
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006228 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006229
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006230 return 0;
6231}
6232
Oliver Endrissebc7de22011-07-03 13:49:44 -03006233static int drxk_c_get_frontend(struct dvb_frontend *fe,
6234 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006235{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006236 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006237 return 0;
6238}
6239
6240static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6241{
6242 struct drxk_state *state = fe->demodulator_priv;
6243 u32 stat;
6244
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006245 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006246 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006247 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006248 if (stat == MPEG_LOCK)
6249 *status |= 0x1f;
6250 if (stat == FEC_LOCK)
6251 *status |= 0x0f;
6252 if (stat == DEMOD_LOCK)
6253 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006254 return 0;
6255}
6256
6257static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6258{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006259 dprintk(1, "\n");
6260
Oliver Endrissebc7de22011-07-03 13:49:44 -03006261 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006262 return 0;
6263}
6264
Oliver Endrissebc7de22011-07-03 13:49:44 -03006265static int drxk_read_signal_strength(struct dvb_frontend *fe,
6266 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006267{
6268 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006269 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006270
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006271 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006272 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006273 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006274 return 0;
6275}
6276
6277static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6278{
6279 struct drxk_state *state = fe->demodulator_priv;
6280 s32 snr2;
6281
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006282 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006283 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006284 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006285 return 0;
6286}
6287
6288static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6289{
6290 struct drxk_state *state = fe->demodulator_priv;
6291 u16 err;
6292
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006293 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006294 DVBTQAMGetAccPktErr(state, &err);
6295 *ucblocks = (u32) err;
6296 return 0;
6297}
6298
Oliver Endrissebc7de22011-07-03 13:49:44 -03006299static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6300 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006301{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006302 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006303 sets->min_delay_ms = 3000;
6304 sets->max_drift = 0;
6305 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006306 return 0;
6307}
6308
Oliver Endrissebc7de22011-07-03 13:49:44 -03006309static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006310{
Mauro Carvalho Chehabc4c3a3d2011-07-14 22:23:18 -03006311 /*
6312 * There's nothing to release here, as the state struct
6313 * is already freed by drxk_c_release.
6314 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006315}
6316
Oliver Endrissebc7de22011-07-03 13:49:44 -03006317static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006318{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006319 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006320
6321 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006322 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006323 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006324 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006325 return 0;
6326}
6327
Oliver Endrissebc7de22011-07-03 13:49:44 -03006328static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006329{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006330 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006331
6332 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006333 mutex_unlock(&state->ctlock);
6334 return 0;
6335}
6336
Oliver Endrissebc7de22011-07-03 13:49:44 -03006337static int drxk_t_get_frontend(struct dvb_frontend *fe,
6338 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006339{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006340 dprintk(1, "\n");
6341
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006342 return 0;
6343}
6344
6345static struct dvb_frontend_ops drxk_c_ops = {
6346 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006347 .name = "DRXK DVB-C",
6348 .type = FE_QAM,
6349 .frequency_stepsize = 62500,
6350 .frequency_min = 47000000,
6351 .frequency_max = 862000000,
6352 .symbol_rate_min = 870000,
6353 .symbol_rate_max = 11700000,
6354 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6355 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006356 .release = drxk_c_release,
6357 .init = drxk_c_init,
6358 .sleep = drxk_c_sleep,
6359 .i2c_gate_ctrl = drxk_gate_ctrl,
6360
6361 .set_frontend = drxk_set_parameters,
6362 .get_frontend = drxk_c_get_frontend,
6363 .get_tune_settings = drxk_c_get_tune_settings,
6364
6365 .read_status = drxk_read_status,
6366 .read_ber = drxk_read_ber,
6367 .read_signal_strength = drxk_read_signal_strength,
6368 .read_snr = drxk_read_snr,
6369 .read_ucblocks = drxk_read_ucblocks,
6370};
6371
6372static struct dvb_frontend_ops drxk_t_ops = {
6373 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006374 .name = "DRXK DVB-T",
6375 .type = FE_OFDM,
6376 .frequency_min = 47125000,
6377 .frequency_max = 865000000,
6378 .frequency_stepsize = 166667,
6379 .frequency_tolerance = 0,
6380 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6381 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6382 FE_CAN_FEC_AUTO |
6383 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6384 FE_CAN_QAM_AUTO |
6385 FE_CAN_TRANSMISSION_MODE_AUTO |
6386 FE_CAN_GUARD_INTERVAL_AUTO |
6387 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006388 .release = drxk_t_release,
6389 .init = drxk_t_init,
6390 .sleep = drxk_t_sleep,
6391 .i2c_gate_ctrl = drxk_gate_ctrl,
6392
6393 .set_frontend = drxk_set_parameters,
6394 .get_frontend = drxk_t_get_frontend,
6395
6396 .read_status = drxk_read_status,
6397 .read_ber = drxk_read_ber,
6398 .read_signal_strength = drxk_read_signal_strength,
6399 .read_snr = drxk_read_snr,
6400 .read_ucblocks = drxk_read_ucblocks,
6401};
6402
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006403struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6404 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006405 struct dvb_frontend **fe_t)
6406{
6407 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006408 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006409
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006410 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006411 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006412 if (!state)
6413 return NULL;
6414
Oliver Endrissebc7de22011-07-03 13:49:44 -03006415 state->i2c = i2c;
6416 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006417 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006418 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006419 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006420 state->antenna_gpio = config->antenna_gpio;
6421 state->antenna_dvbt = config->antenna_dvbt;
6422
6423 /* NOTE: as more UIO bits will be used, add them to the mask */
6424 state->UIO_mask = config->antenna_gpio;
6425
6426 /* Default gpio to DVB-C */
6427 if (!state->antenna_dvbt && state->antenna_gpio)
6428 state->m_GPIO |= state->antenna_gpio;
6429 else
6430 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006431
6432 mutex_init(&state->mutex);
6433 mutex_init(&state->ctlock);
6434
Oliver Endrissebc7de22011-07-03 13:49:44 -03006435 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6436 sizeof(struct dvb_frontend_ops));
6437 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6438 sizeof(struct dvb_frontend_ops));
6439 state->c_frontend.demodulator_priv = state;
6440 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006441
6442 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006443 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006444 goto error;
6445 *fe_t = &state->t_frontend;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006446
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006447 return &state->c_frontend;
6448
6449error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006450 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006451 kfree(state);
6452 return NULL;
6453}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006454EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006455
6456MODULE_DESCRIPTION("DRX-K driver");
6457MODULE_AUTHOR("Ralph Metzler");
6458MODULE_LICENSE("GPL");