blob: 67a1e39d1eabed827083f2d1c7ba51ca8bccb1b7 [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
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -0300684 if (!state->m_ChunkSize)
Mauro Carvalho Chehabde724052011-11-20 11:23:24 -0200685 state->m_ChunkSize = 124;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300686
687 state->m_oscClockFreq = 0;
688 state->m_smartAntInverted = false;
689 state->m_bPDownOpenBridge = false;
690
691 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300692 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300693 /* Timing div, 250ns/Psys */
694 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
695 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
696 HI_I2C_DELAY) / 1000;
697 /* Clipping */
698 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
699 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
700 state->m_HICfgWakeUpKey = (state->demod_address << 1);
701 /* port/bridge/power down ctrl */
702 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
703
704 state->m_bPowerDown = (ulPowerDown != 0);
705
706 state->m_DRXK_A1_PATCH_CODE = false;
707 state->m_DRXK_A1_ROM_CODE = false;
708 state->m_DRXK_A2_ROM_CODE = false;
709 state->m_DRXK_A3_ROM_CODE = false;
710 state->m_DRXK_A2_PATCH_CODE = false;
711 state->m_DRXK_A3_PATCH_CODE = false;
712
713 /* Init AGC and PGA parameters */
714 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300715 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
716 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
717 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
718 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
719 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300720 state->m_vsbPgaCfg = 140;
721
722 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300723 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
724 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
725 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
726 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
727 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
728 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
729 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
730 state->m_vsbPreSawCfg.reference = 0x07;
731 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300732
733 state->m_Quality83percent = DEFAULT_MER_83;
734 state->m_Quality93percent = DEFAULT_MER_93;
735 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
736 state->m_Quality83percent = ulQual83;
737 state->m_Quality93percent = ulQual93;
738 }
739
740 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300741 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
742 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
743 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
744 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
745 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300746
747 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300748 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
749 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
750 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
751 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
752 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
753 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
754 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
755 state->m_atvPreSawCfg.reference = 0x04;
756 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300757
758
759 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300760 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
761 state->m_dvbtRfAgcCfg.outputLevel = 0;
762 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
763 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
764 state->m_dvbtRfAgcCfg.top = 0x2100;
765 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
766 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300767
768
769 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300770 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
771 state->m_dvbtIfAgcCfg.outputLevel = 0;
772 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
773 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
774 state->m_dvbtIfAgcCfg.top = 13424;
775 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
776 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300777 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300778 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
779 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300780
Oliver Endrissebc7de22011-07-03 13:49:44 -0300781 state->m_dvbtPreSawCfg.reference = 4;
782 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300783
784 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300785 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
786 state->m_qamRfAgcCfg.outputLevel = 0;
787 state->m_qamRfAgcCfg.minOutputLevel = 6023;
788 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
789 state->m_qamRfAgcCfg.top = 0x2380;
790 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
791 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300792
793 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300794 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
795 state->m_qamIfAgcCfg.outputLevel = 0;
796 state->m_qamIfAgcCfg.minOutputLevel = 0;
797 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
798 state->m_qamIfAgcCfg.top = 0x0511;
799 state->m_qamIfAgcCfg.cutOffCurrent = 0;
800 state->m_qamIfAgcCfg.speed = 3;
801 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300802 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
803
Oliver Endrissebc7de22011-07-03 13:49:44 -0300804 state->m_qamPgaCfg = 140;
805 state->m_qamPreSawCfg.reference = 4;
806 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300807
808 state->m_OperationMode = OM_NONE;
809 state->m_DrxkState = DRXK_UNINITIALIZED;
810
811 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300812 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
813 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
814 state->m_enableParallel = true; /* If TRUE;
815 parallel out otherwise serial */
816 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
817 state->m_invertERR = false; /* If TRUE; invert ERR signal */
818 state->m_invertSTR = false; /* If TRUE; invert STR signals */
819 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
820 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300821 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300822 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300823 /* If TRUE; static MPEG clockrate will be used;
824 otherwise clockrate will adapt to the bitrate of the TS */
825
826 state->m_DVBTBitrate = ulDVBTBitrate;
827 state->m_DVBCBitrate = ulDVBCBitrate;
828
829 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
830 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
831
832 /* Maximum bitrate in b/s in case static clockrate is selected */
833 state->m_mpegTsStaticBitrate = 19392658;
834 state->m_disableTEIhandling = false;
835
836 if (ulInsertRSByte)
837 state->m_insertRSByte = true;
838
839 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
840 if (ulMpegLockTimeOut < 10000)
841 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
842 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
843 if (ulDemodLockTimeOut < 10000)
844 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
845
Oliver Endrissebc7de22011-07-03 13:49:44 -0300846 /* QAM defaults */
847 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300848 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300849 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
850 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300851
852 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
853 state->m_agcFastClipCtrlDelay = 0;
854
855 state->m_GPIOCfg = (ulGPIOCfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300856
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300857 state->m_bPowerDown = false;
858 state->m_currentPowerMode = DRX_POWER_DOWN;
859
860 state->m_enableParallel = (ulSerialMode == 0);
861
862 state->m_rfmirror = (ulRfMirror == 0);
863 state->m_IfAgcPol = false;
864 return 0;
865}
866
867static int DRXX_Open(struct drxk_state *state)
868{
869 int status = 0;
870 u32 jtag = 0;
871 u16 bid = 0;
872 u16 key = 0;
873
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300874 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300875 /* stop lock indicator process */
876 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
877 if (status < 0)
878 goto error;
879 /* Check device id */
880 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
881 if (status < 0)
882 goto error;
883 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
884 if (status < 0)
885 goto error;
886 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
887 if (status < 0)
888 goto error;
889 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
890 if (status < 0)
891 goto error;
892 status = write16(state, SIO_TOP_COMM_KEY__A, key);
893error:
894 if (status < 0)
895 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300896 return status;
897}
898
899static int GetDeviceCapabilities(struct drxk_state *state)
900{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300901 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300902 u32 sioTopJtagidLo = 0;
903 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300904 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300905
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300906 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300907
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300908 /* driver 0.9.0 */
909 /* stop lock indicator process */
910 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
911 if (status < 0)
912 goto error;
913 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
914 if (status < 0)
915 goto error;
916 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
917 if (status < 0)
918 goto error;
919 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
920 if (status < 0)
921 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300922
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300923 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
924 case 0:
925 /* ignore (bypass ?) */
926 break;
927 case 1:
928 /* 27 MHz */
929 state->m_oscClockFreq = 27000;
930 break;
931 case 2:
932 /* 20.25 MHz */
933 state->m_oscClockFreq = 20250;
934 break;
935 case 3:
936 /* 4 MHz */
937 state->m_oscClockFreq = 20250;
938 break;
939 default:
940 printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
941 return -EINVAL;
942 }
943 /*
944 Determine device capabilities
945 Based on pinning v14
946 */
947 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
948 if (status < 0)
949 goto error;
950 /* driver 0.9.0 */
951 switch ((sioTopJtagidLo >> 29) & 0xF) {
952 case 0:
953 state->m_deviceSpin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300954 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300955 break;
956 case 2:
957 state->m_deviceSpin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300958 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300959 break;
960 case 3:
961 state->m_deviceSpin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300962 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300963 break;
964 default:
965 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
966 status = -EINVAL;
967 printk(KERN_ERR "drxk: Spin unknown\n");
968 goto error2;
969 }
970 switch ((sioTopJtagidLo >> 12) & 0xFF) {
971 case 0x13:
972 /* typeId = DRX3913K_TYPE_ID */
973 state->m_hasLNA = false;
974 state->m_hasOOB = false;
975 state->m_hasATV = false;
976 state->m_hasAudio = false;
977 state->m_hasDVBT = true;
978 state->m_hasDVBC = true;
979 state->m_hasSAWSW = true;
980 state->m_hasGPIO2 = false;
981 state->m_hasGPIO1 = false;
982 state->m_hasIRQN = false;
983 break;
984 case 0x15:
985 /* typeId = DRX3915K_TYPE_ID */
986 state->m_hasLNA = false;
987 state->m_hasOOB = false;
988 state->m_hasATV = true;
989 state->m_hasAudio = false;
990 state->m_hasDVBT = true;
991 state->m_hasDVBC = false;
992 state->m_hasSAWSW = true;
993 state->m_hasGPIO2 = true;
994 state->m_hasGPIO1 = true;
995 state->m_hasIRQN = false;
996 break;
997 case 0x16:
998 /* typeId = DRX3916K_TYPE_ID */
999 state->m_hasLNA = false;
1000 state->m_hasOOB = false;
1001 state->m_hasATV = true;
1002 state->m_hasAudio = false;
1003 state->m_hasDVBT = true;
1004 state->m_hasDVBC = false;
1005 state->m_hasSAWSW = true;
1006 state->m_hasGPIO2 = true;
1007 state->m_hasGPIO1 = true;
1008 state->m_hasIRQN = false;
1009 break;
1010 case 0x18:
1011 /* typeId = DRX3918K_TYPE_ID */
1012 state->m_hasLNA = false;
1013 state->m_hasOOB = false;
1014 state->m_hasATV = true;
1015 state->m_hasAudio = true;
1016 state->m_hasDVBT = true;
1017 state->m_hasDVBC = false;
1018 state->m_hasSAWSW = true;
1019 state->m_hasGPIO2 = true;
1020 state->m_hasGPIO1 = true;
1021 state->m_hasIRQN = false;
1022 break;
1023 case 0x21:
1024 /* typeId = DRX3921K_TYPE_ID */
1025 state->m_hasLNA = false;
1026 state->m_hasOOB = false;
1027 state->m_hasATV = true;
1028 state->m_hasAudio = true;
1029 state->m_hasDVBT = true;
1030 state->m_hasDVBC = true;
1031 state->m_hasSAWSW = true;
1032 state->m_hasGPIO2 = true;
1033 state->m_hasGPIO1 = true;
1034 state->m_hasIRQN = false;
1035 break;
1036 case 0x23:
1037 /* typeId = DRX3923K_TYPE_ID */
1038 state->m_hasLNA = false;
1039 state->m_hasOOB = false;
1040 state->m_hasATV = true;
1041 state->m_hasAudio = true;
1042 state->m_hasDVBT = true;
1043 state->m_hasDVBC = true;
1044 state->m_hasSAWSW = true;
1045 state->m_hasGPIO2 = true;
1046 state->m_hasGPIO1 = true;
1047 state->m_hasIRQN = false;
1048 break;
1049 case 0x25:
1050 /* typeId = DRX3925K_TYPE_ID */
1051 state->m_hasLNA = false;
1052 state->m_hasOOB = false;
1053 state->m_hasATV = true;
1054 state->m_hasAudio = true;
1055 state->m_hasDVBT = true;
1056 state->m_hasDVBC = true;
1057 state->m_hasSAWSW = true;
1058 state->m_hasGPIO2 = true;
1059 state->m_hasGPIO1 = true;
1060 state->m_hasIRQN = false;
1061 break;
1062 case 0x26:
1063 /* typeId = DRX3926K_TYPE_ID */
1064 state->m_hasLNA = false;
1065 state->m_hasOOB = false;
1066 state->m_hasATV = true;
1067 state->m_hasAudio = false;
1068 state->m_hasDVBT = true;
1069 state->m_hasDVBC = true;
1070 state->m_hasSAWSW = true;
1071 state->m_hasGPIO2 = true;
1072 state->m_hasGPIO1 = true;
1073 state->m_hasIRQN = false;
1074 break;
1075 default:
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -03001076 printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001077 ((sioTopJtagidLo >> 12) & 0xFF));
1078 status = -EINVAL;
1079 goto error2;
1080 }
1081
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -03001082 printk(KERN_INFO
1083 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
1084 ((sioTopJtagidLo >> 12) & 0xFF), spin,
1085 state->m_oscClockFreq / 1000,
1086 state->m_oscClockFreq % 1000);
1087
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001088error:
1089 if (status < 0)
1090 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1091
1092error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001093 return status;
1094}
1095
1096static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1097{
1098 int status;
1099 bool powerdown_cmd;
1100
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001101 dprintk(1, "\n");
1102
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001103 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001104 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001105 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001106 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001107 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1108 msleep(1);
1109
1110 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001111 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1112 ((state->m_HICfgCtrl) &
1113 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1114 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001115 if (powerdown_cmd == false) {
1116 /* Wait until command rdy */
1117 u32 retryCount = 0;
1118 u16 waitCmd;
1119
1120 do {
1121 msleep(1);
1122 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001123 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1124 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001125 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1126 && (waitCmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001127 if (status < 0)
1128 goto error;
1129 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001130 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001131error:
1132 if (status < 0)
1133 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1134
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001135 return status;
1136}
1137
1138static int HI_CfgCommand(struct drxk_state *state)
1139{
1140 int status;
1141
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001142 dprintk(1, "\n");
1143
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001144 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001145
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001146 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1147 if (status < 0)
1148 goto error;
1149 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1150 if (status < 0)
1151 goto error;
1152 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1153 if (status < 0)
1154 goto error;
1155 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1156 if (status < 0)
1157 goto error;
1158 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1159 if (status < 0)
1160 goto error;
1161 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1162 if (status < 0)
1163 goto error;
1164 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1165 if (status < 0)
1166 goto error;
1167
1168 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1169error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001170 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001171 if (status < 0)
1172 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001173 return status;
1174}
1175
1176static int InitHI(struct drxk_state *state)
1177{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001178 dprintk(1, "\n");
1179
Oliver Endrissebc7de22011-07-03 13:49:44 -03001180 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001181 state->m_HICfgTimeout = 0x96FF;
1182 /* port/bridge/power down ctrl */
1183 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001184
Oliver Endrissebc7de22011-07-03 13:49:44 -03001185 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001186}
1187
1188static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1189{
1190 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001191 u16 sioPdrMclkCfg = 0;
1192 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001193
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001194 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001195
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001196 /* stop lock indicator process */
1197 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1198 if (status < 0)
1199 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001200
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001201 /* MPEG TS pad configuration */
1202 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1203 if (status < 0)
1204 goto error;
1205
1206 if (mpegEnable == false) {
1207 /* Set MPEG TS pads to inputmode */
1208 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1209 if (status < 0)
1210 goto error;
1211 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1212 if (status < 0)
1213 goto error;
1214 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1215 if (status < 0)
1216 goto error;
1217 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1218 if (status < 0)
1219 goto error;
1220 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1221 if (status < 0)
1222 goto error;
1223 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1224 if (status < 0)
1225 goto error;
1226 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1227 if (status < 0)
1228 goto error;
1229 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1230 if (status < 0)
1231 goto error;
1232 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1233 if (status < 0)
1234 goto error;
1235 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1236 if (status < 0)
1237 goto error;
1238 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1239 if (status < 0)
1240 goto error;
1241 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1242 if (status < 0)
1243 goto error;
1244 } else {
1245 /* Enable MPEG output */
1246 sioPdrMdxCfg =
1247 ((state->m_TSDataStrength <<
1248 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1249 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1250 SIO_PDR_MCLK_CFG_DRIVE__B) |
1251 0x0003);
1252
1253 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1254 if (status < 0)
1255 goto error;
1256 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
1257 if (status < 0)
1258 goto error;
1259 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
1260 if (status < 0)
1261 goto error;
1262 if (state->m_enableParallel == true) {
1263 /* paralel -> enable MD1 to MD7 */
1264 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001265 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001266 goto error;
1267 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001268 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001269 goto error;
1270 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001271 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001272 goto error;
1273 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001274 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001275 goto error;
1276 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001277 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001278 goto error;
1279 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1280 if (status < 0)
1281 goto error;
1282 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1283 if (status < 0)
1284 goto error;
1285 } else {
1286 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1287 SIO_PDR_MD0_CFG_DRIVE__B)
1288 | 0x0003);
1289 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001290 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001291 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001292 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001293 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001294 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001295 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001296 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001297 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001298 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001299 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001300 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001301 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001302 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001303 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001304 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001305 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001306 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001307 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001308 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001309 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001310 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001311 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001312 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001313 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001314 goto error;
1315 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001316 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001317 goto error;
1318 }
1319 /* Enable MB output over MPEG pads and ctl input */
1320 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1321 if (status < 0)
1322 goto error;
1323 /* Write nomagic word to enable pdr reg write */
1324 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1325error:
1326 if (status < 0)
1327 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001328 return status;
1329}
1330
1331static int MPEGTSDisable(struct drxk_state *state)
1332{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001333 dprintk(1, "\n");
1334
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001335 return MPEGTSConfigurePins(state, false);
1336}
1337
1338static int BLChainCmd(struct drxk_state *state,
1339 u16 romOffset, u16 nrOfElements, u32 timeOut)
1340{
1341 u16 blStatus = 0;
1342 int status;
1343 unsigned long end;
1344
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001345 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001346 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001347 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1348 if (status < 0)
1349 goto error;
1350 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1351 if (status < 0)
1352 goto error;
1353 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1354 if (status < 0)
1355 goto error;
1356 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1357 if (status < 0)
1358 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001359
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001360 end = jiffies + msecs_to_jiffies(timeOut);
1361 do {
1362 msleep(1);
1363 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1364 if (status < 0)
1365 goto error;
1366 } while ((blStatus == 0x1) &&
1367 ((time_is_after_jiffies(end))));
1368
1369 if (blStatus == 0x1) {
1370 printk(KERN_ERR "drxk: SIO not ready\n");
1371 status = -EINVAL;
1372 goto error2;
1373 }
1374error:
1375 if (status < 0)
1376 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1377error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001378 mutex_unlock(&state->mutex);
1379 return status;
1380}
1381
1382
1383static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001384 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001385{
1386 const u8 *pSrc = pMCImage;
1387 u16 Flags;
1388 u16 Drain;
1389 u32 Address;
1390 u16 nBlocks;
1391 u16 BlockSize;
1392 u16 BlockCRC;
1393 u32 offset = 0;
1394 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001395 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001396
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001397 dprintk(1, "\n");
1398
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001399 /* down the drain (we don care about MAGIC_WORD) */
1400 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001401 pSrc += sizeof(u16);
1402 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001403 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001404 pSrc += sizeof(u16);
1405 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001406
1407 for (i = 0; i < nBlocks; i += 1) {
1408 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001409 (pSrc[2] << 8) | pSrc[3];
1410 pSrc += sizeof(u32);
1411 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001412
1413 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001414 pSrc += sizeof(u16);
1415 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001416
1417 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001418 pSrc += sizeof(u16);
1419 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001420
1421 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001422 pSrc += sizeof(u16);
1423 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001424
1425 if (offset + BlockSize > Length) {
1426 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1427 return -EINVAL;
1428 }
1429
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001430 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001431 if (status < 0) {
1432 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001433 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001434 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001435 pSrc += BlockSize;
1436 offset += BlockSize;
1437 }
1438 return status;
1439}
1440
1441static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1442{
1443 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001444 u16 data = 0;
1445 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001446 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1447 unsigned long end;
1448
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001449 dprintk(1, "\n");
1450
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001451 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001452 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001453 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1454 }
1455
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001456 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1457 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001458 /* tokenring already has correct status */
1459 return status;
1460 }
1461 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001462 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001463
Oliver Endrissebc7de22011-07-03 13:49:44 -03001464 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001465 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001466 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001467 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001468 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001469 msleep(1);
1470 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001471 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001472 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001473 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001474 }
1475 return status;
1476}
1477
1478static int MPEGTSStop(struct drxk_state *state)
1479{
1480 int status = 0;
1481 u16 fecOcSncMode = 0;
1482 u16 fecOcIprMode = 0;
1483
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001484 dprintk(1, "\n");
1485
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001486 /* Gracefull shutdown (byte boundaries) */
1487 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1488 if (status < 0)
1489 goto error;
1490 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1491 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1492 if (status < 0)
1493 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001494
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001495 /* Suppress MCLK during absence of data */
1496 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1497 if (status < 0)
1498 goto error;
1499 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1500 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1501
1502error:
1503 if (status < 0)
1504 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1505
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001506 return status;
1507}
1508
1509static int scu_command(struct drxk_state *state,
1510 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001511 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001512{
1513#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1514#error DRXK register mapping no longer compatible with this routine!
1515#endif
1516 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001517 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001518 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001519 u8 buffer[34];
1520 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001521 const char *p;
1522 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001523
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001524 dprintk(1, "\n");
1525
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001526 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1527 ((resultLen > 0) && (result == NULL)))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001528 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001529
1530 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001531
1532 /* assume that the command register is ready
1533 since it is checked afterwards */
1534 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1535 buffer[cnt++] = (parameter[ii] & 0xFF);
1536 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1537 }
1538 buffer[cnt++] = (cmd & 0xFF);
1539 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1540
1541 write_block(state, SCU_RAM_PARAM_0__A -
1542 (parameterLen - 1), cnt, buffer);
1543 /* Wait until SCU has processed command */
1544 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001545 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001546 msleep(1);
1547 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1548 if (status < 0)
1549 goto error;
1550 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1551 if (curCmd != DRX_SCU_READY) {
1552 printk(KERN_ERR "drxk: SCU not ready\n");
1553 status = -EIO;
1554 goto error2;
1555 }
1556 /* read results */
1557 if ((resultLen > 0) && (result != NULL)) {
1558 s16 err;
1559 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001560
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001561 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1562 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001563 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001564 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001565 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001566
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001567 /* Check if an error was reported by SCU */
1568 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001569 if (err >= 0)
1570 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001571
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001572 /* check for the known error codes */
1573 switch (err) {
1574 case SCU_RESULT_UNKCMD:
1575 p = "SCU_RESULT_UNKCMD";
1576 break;
1577 case SCU_RESULT_UNKSTD:
1578 p = "SCU_RESULT_UNKSTD";
1579 break;
1580 case SCU_RESULT_SIZE:
1581 p = "SCU_RESULT_SIZE";
1582 break;
1583 case SCU_RESULT_INVPAR:
1584 p = "SCU_RESULT_INVPAR";
1585 break;
1586 default: /* Other negative values are errors */
1587 sprintf(errname, "ERROR: %d\n", err);
1588 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001589 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001590 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1591 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1592 status = -EINVAL;
1593 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001594 }
1595
1596error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001597 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001598 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001599error2:
1600 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001601 return status;
1602}
1603
1604static int SetIqmAf(struct drxk_state *state, bool active)
1605{
1606 u16 data = 0;
1607 int status;
1608
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001609 dprintk(1, "\n");
1610
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001611 /* Configure IQM */
1612 status = read16(state, IQM_AF_STDBY__A, &data);
1613 if (status < 0)
1614 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001615
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001616 if (!active) {
1617 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1618 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1619 | IQM_AF_STDBY_STDBY_PD_STANDBY
1620 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1621 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1622 } else {
1623 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1624 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1625 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1626 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1627 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1628 );
1629 }
1630 status = write16(state, IQM_AF_STDBY__A, data);
1631
1632error:
1633 if (status < 0)
1634 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001635 return status;
1636}
1637
Oliver Endrissebc7de22011-07-03 13:49:44 -03001638static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001639{
1640 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001641 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001642
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001643 dprintk(1, "\n");
1644
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001645 /* Check arguments */
1646 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001647 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001648
1649 switch (*mode) {
1650 case DRX_POWER_UP:
1651 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1652 break;
1653 case DRXK_POWER_DOWN_OFDM:
1654 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1655 break;
1656 case DRXK_POWER_DOWN_CORE:
1657 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1658 break;
1659 case DRXK_POWER_DOWN_PLL:
1660 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1661 break;
1662 case DRX_POWER_DOWN:
1663 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1664 break;
1665 default:
1666 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001667 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001668 }
1669
1670 /* If already in requested power mode, do nothing */
1671 if (state->m_currentPowerMode == *mode)
1672 return 0;
1673
1674 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001675 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001676 status = PowerUpDevice(state);
1677 if (status < 0)
1678 goto error;
1679 status = DVBTEnableOFDMTokenRing(state, true);
1680 if (status < 0)
1681 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001682 }
1683
1684 if (*mode == DRX_POWER_UP) {
1685 /* Restore analog & pin configuartion */
1686 } else {
1687 /* Power down to requested mode */
1688 /* Backup some register settings */
1689 /* Set pins with possible pull-ups connected
1690 to them in input mode */
1691 /* Analog power down */
1692 /* ADC power down */
1693 /* Power down device */
1694 /* stop all comm_exec */
1695 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001696 switch (state->m_OperationMode) {
1697 case OM_DVBT:
1698 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001699 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001700 goto error;
1701 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001702 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001703 goto error;
1704 break;
1705 case OM_QAM_ITU_A:
1706 case OM_QAM_ITU_C:
1707 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001708 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001709 goto error;
1710 status = PowerDownQAM(state);
1711 if (status < 0)
1712 goto error;
1713 break;
1714 default:
1715 break;
1716 }
1717 status = DVBTEnableOFDMTokenRing(state, false);
1718 if (status < 0)
1719 goto error;
1720 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1721 if (status < 0)
1722 goto error;
1723 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1724 if (status < 0)
1725 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001726
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001727 if (*mode != DRXK_POWER_DOWN_OFDM) {
1728 state->m_HICfgCtrl |=
1729 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1730 status = HI_CfgCommand(state);
1731 if (status < 0)
1732 goto error;
1733 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001734 }
1735 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001736
1737error:
1738 if (status < 0)
1739 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1740
Oliver Endrissebc7de22011-07-03 13:49:44 -03001741 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001742}
1743
1744static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1745{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001746 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001747 u16 cmdResult = 0;
1748 u16 data = 0;
1749 int status;
1750
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001751 dprintk(1, "\n");
1752
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001753 status = read16(state, SCU_COMM_EXEC__A, &data);
1754 if (status < 0)
1755 goto error;
1756 if (data == SCU_COMM_EXEC_ACTIVE) {
1757 /* Send OFDM stop command */
1758 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 -03001759 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001760 goto error;
1761 /* Send OFDM reset command */
1762 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1763 if (status < 0)
1764 goto error;
1765 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001766
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001767 /* Reset datapath for OFDM, processors first */
1768 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1769 if (status < 0)
1770 goto error;
1771 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1772 if (status < 0)
1773 goto error;
1774 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1775 if (status < 0)
1776 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001777
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001778 /* powerdown AFE */
1779 status = SetIqmAf(state, false);
1780 if (status < 0)
1781 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001782
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001783 /* powerdown to OFDM mode */
1784 if (setPowerMode) {
1785 status = CtrlPowerMode(state, &powerMode);
1786 if (status < 0)
1787 goto error;
1788 }
1789error:
1790 if (status < 0)
1791 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001792 return status;
1793}
1794
Oliver Endrissebc7de22011-07-03 13:49:44 -03001795static int SetOperationMode(struct drxk_state *state,
1796 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001797{
1798 int status = 0;
1799
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001800 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001801 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001802 Stop and power down previous standard
1803 TODO investigate total power down instead of partial
1804 power down depending on "previous" standard.
1805 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001806
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001807 /* disable HW lock indicator */
1808 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1809 if (status < 0)
1810 goto error;
1811
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001812 /* Device is already at the required mode */
1813 if (state->m_OperationMode == oMode)
1814 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001815
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001816 switch (state->m_OperationMode) {
1817 /* OM_NONE was added for start up */
1818 case OM_NONE:
1819 break;
1820 case OM_DVBT:
1821 status = MPEGTSStop(state);
1822 if (status < 0)
1823 goto error;
1824 status = PowerDownDVBT(state, true);
1825 if (status < 0)
1826 goto error;
1827 state->m_OperationMode = OM_NONE;
1828 break;
1829 case OM_QAM_ITU_A: /* fallthrough */
1830 case OM_QAM_ITU_C:
1831 status = MPEGTSStop(state);
1832 if (status < 0)
1833 goto error;
1834 status = PowerDownQAM(state);
1835 if (status < 0)
1836 goto error;
1837 state->m_OperationMode = OM_NONE;
1838 break;
1839 case OM_QAM_ITU_B:
1840 default:
1841 status = -EINVAL;
1842 goto error;
1843 }
1844
1845 /*
1846 Power up new standard
1847 */
1848 switch (oMode) {
1849 case OM_DVBT:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001850 dprintk(1, ": DVB-T\n");
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001851 state->m_OperationMode = oMode;
1852 status = SetDVBTStandard(state, oMode);
1853 if (status < 0)
1854 goto error;
1855 break;
1856 case OM_QAM_ITU_A: /* fallthrough */
1857 case OM_QAM_ITU_C:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001858 dprintk(1, ": DVB-C Annex %c\n",
1859 (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001860 state->m_OperationMode = oMode;
1861 status = SetQAMStandard(state, oMode);
1862 if (status < 0)
1863 goto error;
1864 break;
1865 case OM_QAM_ITU_B:
1866 default:
1867 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001868 }
1869error:
1870 if (status < 0)
1871 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1872 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001873}
1874
1875static int Start(struct drxk_state *state, s32 offsetFreq,
1876 s32 IntermediateFrequency)
1877{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001878 int status = -EINVAL;
1879
1880 u16 IFreqkHz;
1881 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001882
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001883 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001884 if (state->m_DrxkState != DRXK_STOPPED &&
1885 state->m_DrxkState != DRXK_DTV_STARTED)
1886 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001887
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03001888 state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001889
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001890 if (IntermediateFrequency < 0) {
1891 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1892 IntermediateFrequency = -IntermediateFrequency;
1893 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001894
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001895 switch (state->m_OperationMode) {
1896 case OM_QAM_ITU_A:
1897 case OM_QAM_ITU_C:
1898 IFreqkHz = (IntermediateFrequency / 1000);
1899 status = SetQAM(state, IFreqkHz, OffsetkHz);
1900 if (status < 0)
1901 goto error;
1902 state->m_DrxkState = DRXK_DTV_STARTED;
1903 break;
1904 case OM_DVBT:
1905 IFreqkHz = (IntermediateFrequency / 1000);
1906 status = MPEGTSStop(state);
1907 if (status < 0)
1908 goto error;
1909 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1910 if (status < 0)
1911 goto error;
1912 status = DVBTStart(state);
1913 if (status < 0)
1914 goto error;
1915 state->m_DrxkState = DRXK_DTV_STARTED;
1916 break;
1917 default:
1918 break;
1919 }
1920error:
1921 if (status < 0)
1922 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001923 return status;
1924}
1925
1926static int ShutDown(struct drxk_state *state)
1927{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001928 dprintk(1, "\n");
1929
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001930 MPEGTSStop(state);
1931 return 0;
1932}
1933
Oliver Endrissebc7de22011-07-03 13:49:44 -03001934static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1935 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001936{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001937 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001938
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001939 dprintk(1, "\n");
1940
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001941 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001942 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001943
1944 *pLockStatus = NOT_LOCKED;
1945
1946 /* define the SCU command code */
1947 switch (state->m_OperationMode) {
1948 case OM_QAM_ITU_A:
1949 case OM_QAM_ITU_B:
1950 case OM_QAM_ITU_C:
1951 status = GetQAMLockStatus(state, pLockStatus);
1952 break;
1953 case OM_DVBT:
1954 status = GetDVBTLockStatus(state, pLockStatus);
1955 break;
1956 default:
1957 break;
1958 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001959error:
1960 if (status < 0)
1961 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001962 return status;
1963}
1964
1965static int MPEGTSStart(struct drxk_state *state)
1966{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001967 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001968
1969 u16 fecOcSncMode = 0;
1970
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001971 /* Allow OC to sync again */
1972 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1973 if (status < 0)
1974 goto error;
1975 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1976 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1977 if (status < 0)
1978 goto error;
1979 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1980error:
1981 if (status < 0)
1982 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001983 return status;
1984}
1985
1986static int MPEGTSDtoInit(struct drxk_state *state)
1987{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001988 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001989
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001990 dprintk(1, "\n");
1991
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001992 /* Rate integration settings */
1993 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1994 if (status < 0)
1995 goto error;
1996 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1997 if (status < 0)
1998 goto error;
1999 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
2000 if (status < 0)
2001 goto error;
2002 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
2003 if (status < 0)
2004 goto error;
2005 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2006 if (status < 0)
2007 goto error;
2008 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2009 if (status < 0)
2010 goto error;
2011 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2012 if (status < 0)
2013 goto error;
2014 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2015 if (status < 0)
2016 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002017
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002018 /* Additional configuration */
2019 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2020 if (status < 0)
2021 goto error;
2022 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2023 if (status < 0)
2024 goto error;
2025 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2026error:
2027 if (status < 0)
2028 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2029
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002030 return status;
2031}
2032
Oliver Endrissebc7de22011-07-03 13:49:44 -03002033static int MPEGTSDtoSetup(struct drxk_state *state,
2034 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002035{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002036 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002037
Oliver Endrissebc7de22011-07-03 13:49:44 -03002038 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2039 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2040 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2041 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2042 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2043 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2044 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002045 u16 fecOcTmdMode = 0;
2046 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002047 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002048 bool staticCLK = false;
2049
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002050 dprintk(1, "\n");
2051
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002052 /* Check insertion of the Reed-Solomon parity bytes */
2053 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2054 if (status < 0)
2055 goto error;
2056 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2057 if (status < 0)
2058 goto error;
2059 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2060 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2061 if (state->m_insertRSByte == true) {
2062 /* enable parity symbol forward */
2063 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2064 /* MVAL disable during parity bytes */
2065 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2066 /* TS burst length to 204 */
2067 fecOcDtoBurstLen = 204;
2068 }
2069
2070 /* Check serial or parrallel output */
2071 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2072 if (state->m_enableParallel == false) {
2073 /* MPEG data output is serial -> set ipr_mode[0] */
2074 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2075 }
2076
2077 switch (oMode) {
2078 case OM_DVBT:
2079 maxBitRate = state->m_DVBTBitrate;
2080 fecOcTmdMode = 3;
2081 fecOcRcnCtlRate = 0xC00000;
2082 staticCLK = state->m_DVBTStaticCLK;
2083 break;
2084 case OM_QAM_ITU_A: /* fallthrough */
2085 case OM_QAM_ITU_C:
2086 fecOcTmdMode = 0x0004;
2087 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2088 maxBitRate = state->m_DVBCBitrate;
2089 staticCLK = state->m_DVBCStaticCLK;
2090 break;
2091 default:
2092 status = -EINVAL;
2093 } /* switch (standard) */
2094 if (status < 0)
2095 goto error;
2096
2097 /* Configure DTO's */
2098 if (staticCLK) {
2099 u32 bitRate = 0;
2100
2101 /* Rational DTO for MCLK source (static MCLK rate),
2102 Dynamic DTO for optimal grouping
2103 (avoid intra-packet gaps),
2104 DTO offset enable to sync TS burst with MSTRT */
2105 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2106 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2107 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2108 FEC_OC_FCT_MODE_VIRT_ENA__M);
2109
2110 /* Check user defined bitrate */
2111 bitRate = maxBitRate;
2112 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2113 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002114 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002115 /* Rational DTO period:
2116 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002117
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002118 Result should be floored,
2119 to make sure >= requested bitrate
2120 */
2121 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2122 * 1000) / bitRate);
2123 if (fecOcDtoPeriod <= 2)
2124 fecOcDtoPeriod = 0;
2125 else
2126 fecOcDtoPeriod -= 2;
2127 fecOcTmdIntUpdRate = 8;
2128 } else {
2129 /* (commonAttr->staticCLK == false) => dynamic mode */
2130 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2131 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2132 fecOcTmdIntUpdRate = 5;
2133 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002134
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002135 /* Write appropriate registers with requested configuration */
2136 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2137 if (status < 0)
2138 goto error;
2139 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2140 if (status < 0)
2141 goto error;
2142 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2143 if (status < 0)
2144 goto error;
2145 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2146 if (status < 0)
2147 goto error;
2148 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2149 if (status < 0)
2150 goto error;
2151 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2152 if (status < 0)
2153 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002154
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002155 /* Rate integration settings */
2156 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2157 if (status < 0)
2158 goto error;
2159 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2160 if (status < 0)
2161 goto error;
2162 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2163error:
2164 if (status < 0)
2165 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002166 return status;
2167}
2168
2169static int MPEGTSConfigurePolarity(struct drxk_state *state)
2170{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002171 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002172
2173 /* Data mask for the output data byte */
2174 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002175 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2176 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2177 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2178 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002179
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002180 dprintk(1, "\n");
2181
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002182 /* Control selective inversion of output bits */
2183 fecOcRegIprInvert &= (~(InvertDataMask));
2184 if (state->m_invertDATA == true)
2185 fecOcRegIprInvert |= InvertDataMask;
2186 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2187 if (state->m_invertERR == true)
2188 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2189 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2190 if (state->m_invertSTR == true)
2191 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2192 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2193 if (state->m_invertVAL == true)
2194 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2195 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2196 if (state->m_invertCLK == true)
2197 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002198
2199 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002200}
2201
2202#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2203
2204static int SetAgcRf(struct drxk_state *state,
2205 struct SCfgAgc *pAgcCfg, bool isDTV)
2206{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002207 int status = -EINVAL;
2208 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002209 struct SCfgAgc *pIfAgcSettings;
2210
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002211 dprintk(1, "\n");
2212
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002213 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002214 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002215
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002216 switch (pAgcCfg->ctrlMode) {
2217 case DRXK_AGC_CTRL_AUTO:
2218 /* Enable RF AGC DAC */
2219 status = read16(state, IQM_AF_STDBY__A, &data);
2220 if (status < 0)
2221 goto error;
2222 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2223 status = write16(state, IQM_AF_STDBY__A, data);
2224 if (status < 0)
2225 goto error;
2226 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2227 if (status < 0)
2228 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002229
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002230 /* Enable SCU RF AGC loop */
2231 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002232
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002233 /* Polarity */
2234 if (state->m_RfAgcPol)
2235 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2236 else
2237 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2238 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2239 if (status < 0)
2240 goto error;
2241
2242 /* Set speed (using complementary reduction value) */
2243 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2244 if (status < 0)
2245 goto error;
2246
2247 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2248 data |= (~(pAgcCfg->speed <<
2249 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2250 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2251
2252 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2253 if (status < 0)
2254 goto error;
2255
2256 if (IsDVBT(state))
2257 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2258 else if (IsQAM(state))
2259 pIfAgcSettings = &state->m_qamIfAgcCfg;
2260 else
2261 pIfAgcSettings = &state->m_atvIfAgcCfg;
2262 if (pIfAgcSettings == NULL) {
2263 status = -EINVAL;
2264 goto error;
2265 }
2266
2267 /* Set TOP, only if IF-AGC is in AUTO mode */
2268 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2269 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002270 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002271 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002272
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002273 /* Cut-Off current */
2274 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2275 if (status < 0)
2276 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002277
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002278 /* Max. output level */
2279 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2280 if (status < 0)
2281 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002282
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002283 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002284
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002285 case DRXK_AGC_CTRL_USER:
2286 /* Enable RF AGC DAC */
2287 status = read16(state, IQM_AF_STDBY__A, &data);
2288 if (status < 0)
2289 goto error;
2290 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2291 status = write16(state, IQM_AF_STDBY__A, data);
2292 if (status < 0)
2293 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002294
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002295 /* Disable SCU RF AGC loop */
2296 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2297 if (status < 0)
2298 goto error;
2299 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2300 if (state->m_RfAgcPol)
2301 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2302 else
2303 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2304 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2305 if (status < 0)
2306 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002307
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002308 /* SCU c.o.c. to 0, enabling full control range */
2309 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2310 if (status < 0)
2311 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002312
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002313 /* Write value to output pin */
2314 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2315 if (status < 0)
2316 goto error;
2317 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002318
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002319 case DRXK_AGC_CTRL_OFF:
2320 /* Disable RF AGC DAC */
2321 status = read16(state, IQM_AF_STDBY__A, &data);
2322 if (status < 0)
2323 goto error;
2324 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2325 status = write16(state, IQM_AF_STDBY__A, data);
2326 if (status < 0)
2327 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002328
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002329 /* Disable SCU RF AGC loop */
2330 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2331 if (status < 0)
2332 goto error;
2333 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2334 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2335 if (status < 0)
2336 goto error;
2337 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002338
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002339 default:
2340 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002341
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002342 }
2343error:
2344 if (status < 0)
2345 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002346 return status;
2347}
2348
2349#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2350
Oliver Endrissebc7de22011-07-03 13:49:44 -03002351static int SetAgcIf(struct drxk_state *state,
2352 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002353{
2354 u16 data = 0;
2355 int status = 0;
2356 struct SCfgAgc *pRfAgcSettings;
2357
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002358 dprintk(1, "\n");
2359
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002360 switch (pAgcCfg->ctrlMode) {
2361 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002362
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002363 /* Enable IF AGC DAC */
2364 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002365 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002366 goto error;
2367 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2368 status = write16(state, IQM_AF_STDBY__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 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2373 if (status < 0)
2374 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002375
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002376 /* Enable SCU IF AGC loop */
2377 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2378
2379 /* Polarity */
2380 if (state->m_IfAgcPol)
2381 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2382 else
2383 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2384 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2385 if (status < 0)
2386 goto error;
2387
2388 /* Set speed (using complementary reduction value) */
2389 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2390 if (status < 0)
2391 goto error;
2392 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2393 data |= (~(pAgcCfg->speed <<
2394 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2395 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2396
2397 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2398 if (status < 0)
2399 goto error;
2400
2401 if (IsQAM(state))
2402 pRfAgcSettings = &state->m_qamRfAgcCfg;
2403 else
2404 pRfAgcSettings = &state->m_atvRfAgcCfg;
2405 if (pRfAgcSettings == NULL)
2406 return -1;
2407 /* Restore TOP */
2408 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2409 if (status < 0)
2410 goto error;
2411 break;
2412
2413 case DRXK_AGC_CTRL_USER:
2414
2415 /* Enable IF AGC DAC */
2416 status = read16(state, IQM_AF_STDBY__A, &data);
2417 if (status < 0)
2418 goto error;
2419 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2420 status = write16(state, IQM_AF_STDBY__A, data);
2421 if (status < 0)
2422 goto error;
2423
2424 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2425 if (status < 0)
2426 goto error;
2427
2428 /* Disable SCU IF AGC loop */
2429 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2430
2431 /* Polarity */
2432 if (state->m_IfAgcPol)
2433 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2434 else
2435 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2436 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2437 if (status < 0)
2438 goto error;
2439
2440 /* Write value to output pin */
2441 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2442 if (status < 0)
2443 goto error;
2444 break;
2445
2446 case DRXK_AGC_CTRL_OFF:
2447
2448 /* Disable If AGC DAC */
2449 status = read16(state, IQM_AF_STDBY__A, &data);
2450 if (status < 0)
2451 goto error;
2452 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2453 status = write16(state, IQM_AF_STDBY__A, data);
2454 if (status < 0)
2455 goto error;
2456
2457 /* Disable SCU IF AGC loop */
2458 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2459 if (status < 0)
2460 goto error;
2461 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2462 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2463 if (status < 0)
2464 goto error;
2465 break;
2466 } /* switch (agcSettingsIf->ctrlMode) */
2467
2468 /* always set the top to support
2469 configurations without if-loop */
2470 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2471error:
2472 if (status < 0)
2473 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002474 return status;
2475}
2476
2477static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2478{
2479 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002480 int status;
2481 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002482
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002483 dprintk(1, "\n");
2484
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002485 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2486 if (status < 0) {
2487 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2488 return status;
2489 }
2490
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002491 *pValue = 0;
2492
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002493 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2494 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2495 if (Level < 14000)
2496 *pValue = (14000 - Level) / 4;
2497 else
2498 *pValue = 0;
2499
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002500 return status;
2501}
2502
Oliver Endrissebc7de22011-07-03 13:49:44 -03002503static int GetQAMSignalToNoise(struct drxk_state *state,
2504 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002505{
2506 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002507 u16 qamSlErrPower = 0; /* accum. error between
2508 raw and sliced symbols */
2509 u32 qamSlSigPower = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002510 QAM modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002511 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002512
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002513 dprintk(1, "\n");
2514
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002515 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002516
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002517 /* get the register value needed for MER */
2518 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2519 if (status < 0) {
2520 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2521 return -EINVAL;
2522 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002523
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002524 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002525 case QAM_16:
2526 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2527 break;
2528 case QAM_32:
2529 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2530 break;
2531 case QAM_64:
2532 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2533 break;
2534 case QAM_128:
2535 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2536 break;
2537 default:
2538 case QAM_256:
2539 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2540 break;
2541 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002542
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002543 if (qamSlErrPower > 0) {
2544 qamSlMer = Log10Times100(qamSlSigPower) -
2545 Log10Times100((u32) qamSlErrPower);
2546 }
2547 *pSignalToNoise = qamSlMer;
2548
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002549 return status;
2550}
2551
Oliver Endrissebc7de22011-07-03 13:49:44 -03002552static int GetDVBTSignalToNoise(struct drxk_state *state,
2553 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002554{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002555 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002556 u16 regData = 0;
2557 u32 EqRegTdSqrErrI = 0;
2558 u32 EqRegTdSqrErrQ = 0;
2559 u16 EqRegTdSqrErrExp = 0;
2560 u16 EqRegTdTpsPwrOfs = 0;
2561 u16 EqRegTdReqSmbCnt = 0;
2562 u32 tpsCnt = 0;
2563 u32 SqrErrIQ = 0;
2564 u32 a = 0;
2565 u32 b = 0;
2566 u32 c = 0;
2567 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002568 u16 transmissionParams = 0;
2569
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002570 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002571
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002572 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2573 if (status < 0)
2574 goto error;
2575 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2576 if (status < 0)
2577 goto error;
2578 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2579 if (status < 0)
2580 goto error;
2581 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2582 if (status < 0)
2583 goto error;
2584 /* Extend SQR_ERR_I operational range */
2585 EqRegTdSqrErrI = (u32) regData;
2586 if ((EqRegTdSqrErrExp > 11) &&
2587 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2588 EqRegTdSqrErrI += 0x00010000UL;
2589 }
2590 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2591 if (status < 0)
2592 goto error;
2593 /* Extend SQR_ERR_Q operational range */
2594 EqRegTdSqrErrQ = (u32) regData;
2595 if ((EqRegTdSqrErrExp > 11) &&
2596 (EqRegTdSqrErrQ < 0x00000FFFUL))
2597 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002598
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002599 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2600 if (status < 0)
2601 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002602
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002603 /* Check input data for MER */
2604
2605 /* MER calculation (in 0.1 dB) without math.h */
2606 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2607 iMER = 0;
2608 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2609 /* No error at all, this must be the HW reset value
2610 * Apparently no first measurement yet
2611 * Set MER to 0.0 */
2612 iMER = 0;
2613 } else {
2614 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2615 EqRegTdSqrErrExp;
2616 if ((transmissionParams &
2617 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2618 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2619 tpsCnt = 17;
2620 else
2621 tpsCnt = 68;
2622
2623 /* IMER = 100 * log10 (x)
2624 where x = (EqRegTdTpsPwrOfs^2 *
2625 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2626
2627 => IMER = a + b -c
2628 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2629 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2630 c = 100 * log10 (SqrErrIQ)
2631 */
2632
2633 /* log(x) x = 9bits * 9bits->18 bits */
2634 a = Log10Times100(EqRegTdTpsPwrOfs *
2635 EqRegTdTpsPwrOfs);
2636 /* log(x) x = 16bits * 7bits->23 bits */
2637 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2638 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2639 c = Log10Times100(SqrErrIQ);
2640
2641 iMER = a + b;
2642 /* No negative MER, clip to zero */
2643 if (iMER > c)
2644 iMER -= c;
2645 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002646 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002647 }
2648 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002649
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002650error:
2651 if (status < 0)
2652 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002653 return status;
2654}
2655
2656static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2657{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002658 dprintk(1, "\n");
2659
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002660 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002661 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002662 case OM_DVBT:
2663 return GetDVBTSignalToNoise(state, pSignalToNoise);
2664 case OM_QAM_ITU_A:
2665 case OM_QAM_ITU_C:
2666 return GetQAMSignalToNoise(state, pSignalToNoise);
2667 default:
2668 break;
2669 }
2670 return 0;
2671}
2672
2673#if 0
2674static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2675{
2676 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2677 int status = 0;
2678
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002679 dprintk(1, "\n");
2680
Oliver Endrissebc7de22011-07-03 13:49:44 -03002681 static s32 QE_SN[] = {
2682 51, /* QPSK 1/2 */
2683 69, /* QPSK 2/3 */
2684 79, /* QPSK 3/4 */
2685 89, /* QPSK 5/6 */
2686 97, /* QPSK 7/8 */
2687 108, /* 16-QAM 1/2 */
2688 131, /* 16-QAM 2/3 */
2689 146, /* 16-QAM 3/4 */
2690 156, /* 16-QAM 5/6 */
2691 160, /* 16-QAM 7/8 */
2692 165, /* 64-QAM 1/2 */
2693 187, /* 64-QAM 2/3 */
2694 202, /* 64-QAM 3/4 */
2695 216, /* 64-QAM 5/6 */
2696 225, /* 64-QAM 7/8 */
2697 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002698
2699 *pQuality = 0;
2700
2701 do {
2702 s32 SignalToNoise = 0;
2703 u16 Constellation = 0;
2704 u16 CodeRate = 0;
2705 u32 SignalToNoiseRel;
2706 u32 BERQuality;
2707
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002708 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2709 if (status < 0)
2710 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002711 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002712 if (status < 0)
2713 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002714 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2715
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002716 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002717 if (status < 0)
2718 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002719 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2720
2721 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2722 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2723 break;
2724 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002725 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002726 BERQuality = 100;
2727
Oliver Endrissebc7de22011-07-03 13:49:44 -03002728 if (SignalToNoiseRel < -70)
2729 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002730 else if (SignalToNoiseRel < 30)
2731 *pQuality = ((SignalToNoiseRel + 70) *
2732 BERQuality) / 100;
2733 else
2734 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002735 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002736 return 0;
2737};
2738
Oliver Endrissebc7de22011-07-03 13:49:44 -03002739static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002740{
2741 int status = 0;
2742 *pQuality = 0;
2743
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002744 dprintk(1, "\n");
2745
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002746 do {
2747 u32 SignalToNoise = 0;
2748 u32 BERQuality = 100;
2749 u32 SignalToNoiseRel = 0;
2750
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002751 status = GetQAMSignalToNoise(state, &SignalToNoise);
2752 if (status < 0)
2753 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002754
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002755 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002756 case QAM_16:
2757 SignalToNoiseRel = SignalToNoise - 200;
2758 break;
2759 case QAM_32:
2760 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002761 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002762 case QAM_64:
2763 SignalToNoiseRel = SignalToNoise - 260;
2764 break;
2765 case QAM_128:
2766 SignalToNoiseRel = SignalToNoise - 290;
2767 break;
2768 default:
2769 case QAM_256:
2770 SignalToNoiseRel = SignalToNoise - 320;
2771 break;
2772 }
2773
2774 if (SignalToNoiseRel < -70)
2775 *pQuality = 0;
2776 else if (SignalToNoiseRel < 30)
2777 *pQuality = ((SignalToNoiseRel + 70) *
2778 BERQuality) / 100;
2779 else
2780 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002781 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002782
2783 return status;
2784}
2785
2786static int GetQuality(struct drxk_state *state, s32 *pQuality)
2787{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002788 dprintk(1, "\n");
2789
Oliver Endrissebc7de22011-07-03 13:49:44 -03002790 switch (state->m_OperationMode) {
2791 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002792 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002793 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002794 return GetDVBCQuality(state, pQuality);
2795 default:
2796 break;
2797 }
2798
2799 return 0;
2800}
2801#endif
2802
2803/* Free data ram in SIO HI */
2804#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2805#define SIO_HI_RA_RAM_USR_END__A 0x420060
2806
2807#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2808#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2809#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2810#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2811
2812#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2813#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2814#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2815
2816static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2817{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002818 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002819
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002820 dprintk(1, "\n");
2821
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002822 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002823 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002824 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002825 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002826
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002827 if (state->no_i2c_bridge)
2828 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002829
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002830 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2831 if (status < 0)
2832 goto error;
2833 if (bEnableBridge) {
2834 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 -03002835 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002836 goto error;
2837 } else {
2838 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2839 if (status < 0)
2840 goto error;
2841 }
2842
2843 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2844
2845error:
2846 if (status < 0)
2847 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002848 return status;
2849}
2850
Oliver Endrissebc7de22011-07-03 13:49:44 -03002851static int SetPreSaw(struct drxk_state *state,
2852 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002853{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002854 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002855
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002856 dprintk(1, "\n");
2857
Oliver Endrissebc7de22011-07-03 13:49:44 -03002858 if ((pPreSawCfg == NULL)
2859 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002860 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002861
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002862 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002863error:
2864 if (status < 0)
2865 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002866 return status;
2867}
2868
2869static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002870 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002871{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002872 u16 blStatus = 0;
2873 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2874 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2875 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002876 unsigned long end;
2877
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002878 dprintk(1, "\n");
2879
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002880 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002881 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2882 if (status < 0)
2883 goto error;
2884 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2885 if (status < 0)
2886 goto error;
2887 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2888 if (status < 0)
2889 goto error;
2890 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2891 if (status < 0)
2892 goto error;
2893 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2894 if (status < 0)
2895 goto error;
2896 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2897 if (status < 0)
2898 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002899
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002900 end = jiffies + msecs_to_jiffies(timeOut);
2901 do {
2902 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2903 if (status < 0)
2904 goto error;
2905 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2906 if (blStatus == 0x1) {
2907 printk(KERN_ERR "drxk: SIO not ready\n");
2908 status = -EINVAL;
2909 goto error2;
2910 }
2911error:
2912 if (status < 0)
2913 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2914error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002915 mutex_unlock(&state->mutex);
2916 return status;
2917
2918}
2919
Oliver Endrissebc7de22011-07-03 13:49:44 -03002920static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002921{
2922 u16 data = 0;
2923 int status;
2924
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002925 dprintk(1, "\n");
2926
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002927 /* Start measurement */
2928 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2929 if (status < 0)
2930 goto error;
2931 status = write16(state, IQM_AF_START_LOCK__A, 1);
2932 if (status < 0)
2933 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002934
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002935 *count = 0;
2936 status = read16(state, IQM_AF_PHASE0__A, &data);
2937 if (status < 0)
2938 goto error;
2939 if (data == 127)
2940 *count = *count + 1;
2941 status = read16(state, IQM_AF_PHASE1__A, &data);
2942 if (status < 0)
2943 goto error;
2944 if (data == 127)
2945 *count = *count + 1;
2946 status = read16(state, IQM_AF_PHASE2__A, &data);
2947 if (status < 0)
2948 goto error;
2949 if (data == 127)
2950 *count = *count + 1;
2951
2952error:
2953 if (status < 0)
2954 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002955 return status;
2956}
2957
2958static int ADCSynchronization(struct drxk_state *state)
2959{
2960 u16 count = 0;
2961 int status;
2962
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002963 dprintk(1, "\n");
2964
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002965 status = ADCSyncMeasurement(state, &count);
2966 if (status < 0)
2967 goto error;
2968
2969 if (count == 1) {
2970 /* Try sampling on a diffrent edge */
2971 u16 clkNeg = 0;
2972
2973 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2974 if (status < 0)
2975 goto error;
2976 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2977 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2978 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2979 clkNeg |=
2980 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2981 } else {
2982 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2983 clkNeg |=
2984 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2985 }
2986 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2987 if (status < 0)
2988 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002989 status = ADCSyncMeasurement(state, &count);
2990 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002991 goto error;
2992 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002993
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002994 if (count < 2)
2995 status = -EINVAL;
2996error:
2997 if (status < 0)
2998 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002999 return status;
3000}
3001
3002static int SetFrequencyShifter(struct drxk_state *state,
3003 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003004 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003005{
3006 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003007 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003008 u32 fmFrequencyShift = 0;
3009 bool tunerMirror = !state->m_bMirrorFreqSpect;
3010 u32 adcFreq;
3011 bool adcFlip;
3012 int status;
3013 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003014 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003015 u32 frequencyShift;
3016 bool imageToSelect;
3017
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003018 dprintk(1, "\n");
3019
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003020 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003021 Program frequency shifter
3022 No need to account for mirroring on RF
3023 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003024 if (isDTV) {
3025 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3026 (state->m_OperationMode == OM_QAM_ITU_C) ||
3027 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003028 selectPosImage = true;
3029 else
3030 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003031 }
3032 if (tunerMirror)
3033 /* tuner doesn't mirror */
3034 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003035 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003036 else
3037 /* tuner mirrors */
3038 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003039 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003040 if (ifFreqActual > samplingFrequency / 2) {
3041 /* adc mirrors */
3042 adcFreq = samplingFrequency - ifFreqActual;
3043 adcFlip = true;
3044 } else {
3045 /* adc doesn't mirror */
3046 adcFreq = ifFreqActual;
3047 adcFlip = false;
3048 }
3049
3050 frequencyShift = adcFreq;
3051 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003052 adcFlip ^ selectPosImage;
3053 state->m_IqmFsRateOfs =
3054 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003055
3056 if (imageToSelect)
3057 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3058
3059 /* Program frequency shifter with tuner offset compensation */
3060 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003061 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3062 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003063 if (status < 0)
3064 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003065 return status;
3066}
3067
3068static int InitAGC(struct drxk_state *state, bool isDTV)
3069{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003070 u16 ingainTgt = 0;
3071 u16 ingainTgtMin = 0;
3072 u16 ingainTgtMax = 0;
3073 u16 clpCyclen = 0;
3074 u16 clpSumMin = 0;
3075 u16 clpDirTo = 0;
3076 u16 snsSumMin = 0;
3077 u16 snsSumMax = 0;
3078 u16 clpSumMax = 0;
3079 u16 snsDirTo = 0;
3080 u16 kiInnergainMin = 0;
3081 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003082 u16 ifIaccuHiTgtMin = 0;
3083 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003084 u16 data = 0;
3085 u16 fastClpCtrlDelay = 0;
3086 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003087 int status = 0;
3088
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003089 dprintk(1, "\n");
3090
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003091 /* Common settings */
3092 snsSumMax = 1023;
3093 ifIaccuHiTgtMin = 2047;
3094 clpCyclen = 500;
3095 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003096
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003097 /* AGCInit() not available for DVBT; init done in microcode */
3098 if (!IsQAM(state)) {
3099 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3100 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003101 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003102
3103 /* FIXME: Analog TV AGC require different settings */
3104
3105 /* Standard specific settings */
3106 clpSumMin = 8;
3107 clpDirTo = (u16) -9;
3108 clpCtrlMode = 0;
3109 snsSumMin = 8;
3110 snsDirTo = (u16) -9;
3111 kiInnergainMin = (u16) -1030;
3112 ifIaccuHiTgtMax = 0x2380;
3113 ifIaccuHiTgt = 0x2380;
3114 ingainTgtMin = 0x0511;
3115 ingainTgt = 0x0511;
3116 ingainTgtMax = 5119;
3117 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3118
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003119 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3120 if (status < 0)
3121 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003122
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003123 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3124 if (status < 0)
3125 goto error;
3126 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3127 if (status < 0)
3128 goto error;
3129 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3130 if (status < 0)
3131 goto error;
3132 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3133 if (status < 0)
3134 goto error;
3135 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3136 if (status < 0)
3137 goto error;
3138 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3139 if (status < 0)
3140 goto error;
3141 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3142 if (status < 0)
3143 goto error;
3144 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3145 if (status < 0)
3146 goto error;
3147 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3148 if (status < 0)
3149 goto error;
3150 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3151 if (status < 0)
3152 goto error;
3153 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3154 if (status < 0)
3155 goto error;
3156 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3157 if (status < 0)
3158 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003159
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003160 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3161 if (status < 0)
3162 goto error;
3163 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3164 if (status < 0)
3165 goto error;
3166 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3167 if (status < 0)
3168 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003169
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003170 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3171 if (status < 0)
3172 goto error;
3173 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3174 if (status < 0)
3175 goto error;
3176 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3177 if (status < 0)
3178 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003179
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003180 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3181 if (status < 0)
3182 goto error;
3183 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3184 if (status < 0)
3185 goto error;
3186 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3187 if (status < 0)
3188 goto error;
3189 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3190 if (status < 0)
3191 goto error;
3192 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3193 if (status < 0)
3194 goto error;
3195 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3196 if (status < 0)
3197 goto error;
3198 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3199 if (status < 0)
3200 goto error;
3201 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3202 if (status < 0)
3203 goto error;
3204 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3205 if (status < 0)
3206 goto error;
3207 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3208 if (status < 0)
3209 goto error;
3210 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3211 if (status < 0)
3212 goto error;
3213 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3214 if (status < 0)
3215 goto error;
3216 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3217 if (status < 0)
3218 goto error;
3219 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3220 if (status < 0)
3221 goto error;
3222 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3223 if (status < 0)
3224 goto error;
3225 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3226 if (status < 0)
3227 goto error;
3228 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3229 if (status < 0)
3230 goto error;
3231 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3232 if (status < 0)
3233 goto error;
3234 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3235 if (status < 0)
3236 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003237
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003238 /* Initialize inner-loop KI gain factors */
3239 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3240 if (status < 0)
3241 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003242
3243 data = 0x0657;
3244 data &= ~SCU_RAM_AGC_KI_RF__M;
3245 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3246 data &= ~SCU_RAM_AGC_KI_IF__M;
3247 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3248
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003249 status = write16(state, SCU_RAM_AGC_KI__A, data);
3250error:
3251 if (status < 0)
3252 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003253 return status;
3254}
3255
Oliver Endrissebc7de22011-07-03 13:49:44 -03003256static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003257{
3258 int status;
3259
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003260 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003261 if (packetErr == NULL)
3262 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3263 else
3264 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3265 if (status < 0)
3266 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003267 return status;
3268}
3269
3270static int DVBTScCommand(struct drxk_state *state,
3271 u16 cmd, u16 subcmd,
3272 u16 param0, u16 param1, u16 param2,
3273 u16 param3, u16 param4)
3274{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003275 u16 curCmd = 0;
3276 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003277 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003278 u16 scExec = 0;
3279 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003280
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003281 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003282 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003283 if (scExec != 1) {
3284 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003285 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003286 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003287 if (status < 0)
3288 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003289
3290 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003291 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003292 do {
3293 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003294 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003295 retryCnt++;
3296 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003297 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3298 goto error;
3299
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003300 /* Write sub-command */
3301 switch (cmd) {
3302 /* All commands using sub-cmd */
3303 case OFDM_SC_RA_RAM_CMD_PROC_START:
3304 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3305 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003306 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3307 if (status < 0)
3308 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003309 break;
3310 default:
3311 /* Do nothing */
3312 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003313 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003314
3315 /* Write needed parameters and the command */
3316 switch (cmd) {
3317 /* All commands using 5 parameters */
3318 /* All commands using 4 parameters */
3319 /* All commands using 3 parameters */
3320 /* All commands using 2 parameters */
3321 case OFDM_SC_RA_RAM_CMD_PROC_START:
3322 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3323 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003324 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003325 /* All commands using 1 parameters */
3326 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3327 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003328 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003329 /* All commands using 0 parameters */
3330 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3331 case OFDM_SC_RA_RAM_CMD_NULL:
3332 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003333 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003334 break;
3335 default:
3336 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003337 status = -EINVAL;
3338 }
3339 if (status < 0)
3340 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003341
3342 /* Wait until sc is ready processing command */
3343 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003344 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003345 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003346 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003347 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003348 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003349 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3350 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003351
3352 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003353 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003354 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003355 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003356 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003357 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003358 if (status < 0)
3359 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003360
3361 /* Retreive results parameters from SC */
3362 switch (cmd) {
3363 /* All commands yielding 5 results */
3364 /* All commands yielding 4 results */
3365 /* All commands yielding 3 results */
3366 /* All commands yielding 2 results */
3367 /* All commands yielding 1 result */
3368 case OFDM_SC_RA_RAM_CMD_USER_IO:
3369 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003370 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003371 /* All commands yielding 0 results */
3372 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3373 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3374 case OFDM_SC_RA_RAM_CMD_PROC_START:
3375 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3376 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3377 case OFDM_SC_RA_RAM_CMD_NULL:
3378 break;
3379 default:
3380 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003381 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003382 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003383 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003384error:
3385 if (status < 0)
3386 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003387 return status;
3388}
3389
Oliver Endrissebc7de22011-07-03 13:49:44 -03003390static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003391{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003392 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003393 int status;
3394
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003395 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003396 status = CtrlPowerMode(state, &powerMode);
3397 if (status < 0)
3398 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003399 return status;
3400}
3401
Oliver Endrissebc7de22011-07-03 13:49:44 -03003402static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003403{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003404 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003405
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003406 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003407 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003408 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003409 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003410 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003411 if (status < 0)
3412 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003413 return status;
3414}
3415
3416#define DEFAULT_FR_THRES_8K 4000
3417static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3418{
3419
3420 int status;
3421
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003422 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003423 if (*enabled == true) {
3424 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003425 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003426 DEFAULT_FR_THRES_8K);
3427 } else {
3428 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003429 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003430 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003431 if (status < 0)
3432 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003433
3434 return status;
3435}
3436
3437static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3438 struct DRXKCfgDvbtEchoThres_t *echoThres)
3439{
3440 u16 data = 0;
3441 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003442
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003443 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003444 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3445 if (status < 0)
3446 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003447
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003448 switch (echoThres->fftMode) {
3449 case DRX_FFTMODE_2K:
3450 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3451 data |= ((echoThres->threshold <<
3452 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3453 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003454 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003455 case DRX_FFTMODE_8K:
3456 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3457 data |= ((echoThres->threshold <<
3458 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3459 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003460 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003461 default:
3462 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003463 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003464
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003465 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3466error:
3467 if (status < 0)
3468 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003469 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003470}
3471
3472static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003473 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003474{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003475 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003476
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003477 dprintk(1, "\n");
3478
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003479 switch (*speed) {
3480 case DRXK_DVBT_SQI_SPEED_FAST:
3481 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3482 case DRXK_DVBT_SQI_SPEED_SLOW:
3483 break;
3484 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003485 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003486 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003487 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003488 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003489error:
3490 if (status < 0)
3491 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003492 return status;
3493}
3494
3495/*============================================================================*/
3496
3497/**
3498* \brief Activate DVBT specific presets
3499* \param demod instance of demodulator.
3500* \return DRXStatus_t.
3501*
3502* Called in DVBTSetStandard
3503*
3504*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003505static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003506{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003507 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003508 bool setincenable = false;
3509 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003510
Oliver Endrissebc7de22011-07-03 13:49:44 -03003511 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3512 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003513
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003514 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003515 status = DVBTCtrlSetIncEnable(state, &setincenable);
3516 if (status < 0)
3517 goto error;
3518 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3519 if (status < 0)
3520 goto error;
3521 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3522 if (status < 0)
3523 goto error;
3524 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3525 if (status < 0)
3526 goto error;
3527 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3528error:
3529 if (status < 0)
3530 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003531 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003532}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003533
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003534/*============================================================================*/
3535
3536/**
3537* \brief Initialize channelswitch-independent settings for DVBT.
3538* \param demod instance of demodulator.
3539* \return DRXStatus_t.
3540*
3541* For ROM code channel filter taps are loaded from the bootloader. For microcode
3542* the DVB-T taps from the drxk_filters.h are used.
3543*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003544static int SetDVBTStandard(struct drxk_state *state,
3545 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003546{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003547 u16 cmdResult = 0;
3548 u16 data = 0;
3549 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003550
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003551 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003552
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003553 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003554 /* added antenna switch */
3555 SwitchAntennaToDVBT(state);
3556 /* send OFDM reset command */
3557 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 -03003558 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003559 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003560
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003561 /* send OFDM setenv command */
3562 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3563 if (status < 0)
3564 goto error;
3565
3566 /* reset datapath for OFDM, processors first */
3567 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3568 if (status < 0)
3569 goto error;
3570 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3571 if (status < 0)
3572 goto error;
3573 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3574 if (status < 0)
3575 goto error;
3576
3577 /* IQM setup */
3578 /* synchronize on ofdstate->m_festart */
3579 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3580 if (status < 0)
3581 goto error;
3582 /* window size for clipping ADC detection */
3583 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3584 if (status < 0)
3585 goto error;
3586 /* window size for for sense pre-SAW detection */
3587 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3588 if (status < 0)
3589 goto error;
3590 /* sense threshold for sense pre-SAW detection */
3591 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3592 if (status < 0)
3593 goto error;
3594 status = SetIqmAf(state, true);
3595 if (status < 0)
3596 goto error;
3597
3598 status = write16(state, IQM_AF_AGC_RF__A, 0);
3599 if (status < 0)
3600 goto error;
3601
3602 /* Impulse noise cruncher setup */
3603 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3604 if (status < 0)
3605 goto error;
3606 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3607 if (status < 0)
3608 goto error;
3609 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3610 if (status < 0)
3611 goto error;
3612
3613 status = write16(state, IQM_RC_STRETCH__A, 16);
3614 if (status < 0)
3615 goto error;
3616 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3617 if (status < 0)
3618 goto error;
3619 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3620 if (status < 0)
3621 goto error;
3622 status = write16(state, IQM_CF_SCALE__A, 1600);
3623 if (status < 0)
3624 goto error;
3625 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3626 if (status < 0)
3627 goto error;
3628
3629 /* virtual clipping threshold for clipping ADC detection */
3630 status = write16(state, IQM_AF_CLP_TH__A, 448);
3631 if (status < 0)
3632 goto error;
3633 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3634 if (status < 0)
3635 goto error;
3636
3637 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3638 if (status < 0)
3639 goto error;
3640
3641 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3642 if (status < 0)
3643 goto error;
3644 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3645 if (status < 0)
3646 goto error;
3647 /* enable power measurement interrupt */
3648 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3649 if (status < 0)
3650 goto error;
3651 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3652 if (status < 0)
3653 goto error;
3654
3655 /* IQM will not be reset from here, sync ADC and update/init AGC */
3656 status = ADCSynchronization(state);
3657 if (status < 0)
3658 goto error;
3659 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3660 if (status < 0)
3661 goto error;
3662
3663 /* Halt SCU to enable safe non-atomic accesses */
3664 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3665 if (status < 0)
3666 goto error;
3667
3668 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3669 if (status < 0)
3670 goto error;
3671 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3672 if (status < 0)
3673 goto error;
3674
3675 /* Set Noise Estimation notch width and enable DC fix */
3676 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3677 if (status < 0)
3678 goto error;
3679 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3680 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3681 if (status < 0)
3682 goto error;
3683
3684 /* Activate SCU to enable SCU commands */
3685 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3686 if (status < 0)
3687 goto error;
3688
3689 if (!state->m_DRXK_A3_ROM_CODE) {
3690 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3691 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3692 if (status < 0)
3693 goto error;
3694 }
3695
3696 /* OFDM_SC setup */
3697#ifdef COMPILE_FOR_NONRT
3698 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3699 if (status < 0)
3700 goto error;
3701 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3702 if (status < 0)
3703 goto error;
3704#endif
3705
3706 /* FEC setup */
3707 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3708 if (status < 0)
3709 goto error;
3710
3711
3712#ifdef COMPILE_FOR_NONRT
3713 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3714 if (status < 0)
3715 goto error;
3716#else
3717 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3718 if (status < 0)
3719 goto error;
3720#endif
3721 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3722 if (status < 0)
3723 goto error;
3724
3725 /* Setup MPEG bus */
3726 status = MPEGTSDtoSetup(state, OM_DVBT);
3727 if (status < 0)
3728 goto error;
3729 /* Set DVBT Presets */
3730 status = DVBTActivatePresets(state);
3731 if (status < 0)
3732 goto error;
3733
3734error:
3735 if (status < 0)
3736 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003737 return status;
3738}
3739
3740/*============================================================================*/
3741/**
3742* \brief Start dvbt demodulating for channel.
3743* \param demod instance of demodulator.
3744* \return DRXStatus_t.
3745*/
3746static int DVBTStart(struct drxk_state *state)
3747{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003748 u16 param1;
3749 int status;
3750 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003751
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003752 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003753 /* Start correct processes to get in lock */
3754 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003755 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3756 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3757 if (status < 0)
3758 goto error;
3759 /* Start FEC OC */
3760 status = MPEGTSStart(state);
3761 if (status < 0)
3762 goto error;
3763 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3764 if (status < 0)
3765 goto error;
3766error:
3767 if (status < 0)
3768 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003769 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003770}
3771
3772
3773/*============================================================================*/
3774
3775/**
3776* \brief Set up dvbt demodulator for channel.
3777* \param demod instance of demodulator.
3778* \return DRXStatus_t.
3779* // original DVBTSetChannel()
3780*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003781static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3782 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003783{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003784 u16 cmdResult = 0;
3785 u16 transmissionParams = 0;
3786 u16 operationMode = 0;
3787 u32 iqmRcRateOfs = 0;
3788 u32 bandwidth = 0;
3789 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003790 int status;
3791
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003792 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003793
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003794 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3795 if (status < 0)
3796 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003797
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003798 /* Halt SCU to enable safe non-atomic accesses */
3799 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3800 if (status < 0)
3801 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003802
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003803 /* Stop processors */
3804 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3805 if (status < 0)
3806 goto error;
3807 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3808 if (status < 0)
3809 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003810
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003811 /* Mandatory fix, always stop CP, required to set spl offset back to
3812 hardware default (is set to 0 by ucode during pilot detection */
3813 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3814 if (status < 0)
3815 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003816
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003817 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003818
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003819 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003820 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003821 case TRANSMISSION_MODE_AUTO:
3822 default:
3823 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3824 /* fall through , try first guess DRX_FFTMODE_8K */
3825 case TRANSMISSION_MODE_8K:
3826 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003827 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003828 case TRANSMISSION_MODE_2K:
3829 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003830 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003831 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003832
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003833 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003834 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003835 default:
3836 case GUARD_INTERVAL_AUTO:
3837 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3838 /* fall through , try first guess DRX_GUARD_1DIV4 */
3839 case GUARD_INTERVAL_1_4:
3840 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003841 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003842 case GUARD_INTERVAL_1_32:
3843 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003844 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003845 case GUARD_INTERVAL_1_16:
3846 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003847 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003848 case GUARD_INTERVAL_1_8:
3849 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003850 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003851 }
3852
3853 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003854 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003855 case HIERARCHY_AUTO:
3856 case HIERARCHY_NONE:
3857 default:
3858 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3859 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3860 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3861 /* break; */
3862 case HIERARCHY_1:
3863 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3864 break;
3865 case HIERARCHY_2:
3866 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3867 break;
3868 case HIERARCHY_4:
3869 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3870 break;
3871 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003872
3873
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003874 /* modulation */
3875 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003876 case QAM_AUTO:
3877 default:
3878 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3879 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3880 case QAM_64:
3881 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3882 break;
3883 case QPSK:
3884 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3885 break;
3886 case QAM_16:
3887 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3888 break;
3889 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003890#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003891 /* No hierachical channels support in BDA */
3892 /* Priority (only for hierarchical channels) */
3893 switch (channel->priority) {
3894 case DRX_PRIORITY_LOW:
3895 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3896 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3897 OFDM_EC_SB_PRIOR_LO);
3898 break;
3899 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003900 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003901 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3902 OFDM_EC_SB_PRIOR_HI));
3903 break;
3904 case DRX_PRIORITY_UNKNOWN: /* fall through */
3905 default:
3906 status = -EINVAL;
3907 goto error;
3908 }
3909#else
3910 /* Set Priorty high */
3911 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3912 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3913 if (status < 0)
3914 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003915#endif
3916
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003917 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003918 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003919 case FEC_AUTO:
3920 default:
3921 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3922 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3923 case FEC_2_3:
3924 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3925 break;
3926 case FEC_1_2:
3927 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3928 break;
3929 case FEC_3_4:
3930 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3931 break;
3932 case FEC_5_6:
3933 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3934 break;
3935 case FEC_7_8:
3936 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3937 break;
3938 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003939
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003940 /* SAW filter selection: normaly not necesarry, but if wanted
3941 the application can select a SAW filter via the driver by using UIOs */
3942 /* First determine real bandwidth (Hz) */
3943 /* Also set delay for impulse noise cruncher */
3944 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3945 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3946 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003947 switch (state->props.bandwidth_hz) {
3948 case 0:
3949 state->props.bandwidth_hz = 8000000;
3950 /* fall though */
3951 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003952 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3953 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003954 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003955 goto error;
3956 /* cochannel protection for PAL 8 MHz */
3957 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3958 if (status < 0)
3959 goto error;
3960 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3961 if (status < 0)
3962 goto error;
3963 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3964 if (status < 0)
3965 goto error;
3966 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3967 if (status < 0)
3968 goto error;
3969 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003970 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003971 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3972 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3973 if (status < 0)
3974 goto error;
3975 /* cochannel protection for PAL 7 MHz */
3976 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3977 if (status < 0)
3978 goto error;
3979 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3980 if (status < 0)
3981 goto error;
3982 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3983 if (status < 0)
3984 goto error;
3985 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3986 if (status < 0)
3987 goto error;
3988 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003989 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003990 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3991 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3992 if (status < 0)
3993 goto error;
3994 /* cochannel protection for NTSC 6 MHz */
3995 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3996 if (status < 0)
3997 goto error;
3998 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3999 if (status < 0)
4000 goto error;
4001 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
4002 if (status < 0)
4003 goto error;
4004 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
4005 if (status < 0)
4006 goto error;
4007 break;
4008 default:
4009 status = -EINVAL;
4010 goto error;
4011 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004012
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004013 if (iqmRcRateOfs == 0) {
4014 /* Now compute IQM_RC_RATE_OFS
4015 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4016 =>
4017 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4018 */
4019 /* (SysFreq / BandWidth) * (2^28) */
4020 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4021 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4022 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4023 iqmRcRateOfs = Frac28a((u32)
4024 ((state->m_sysClockFreq *
4025 1000) / 3), bandwidth);
4026 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4027 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4028 iqmRcRateOfs += 0x80L;
4029 iqmRcRateOfs = iqmRcRateOfs >> 7;
4030 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4031 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4032 }
4033
4034 iqmRcRateOfs &=
4035 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4036 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4037 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4038 if (status < 0)
4039 goto error;
4040
4041 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004042
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004043#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004044 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4045 if (status < 0)
4046 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004047#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004048 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4049 if (status < 0)
4050 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004051
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004052 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004053
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004054 /* Activate SCU to enable SCU commands */
4055 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4056 if (status < 0)
4057 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004058
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004059 /* Enable SC after setting all other parameters */
4060 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4061 if (status < 0)
4062 goto error;
4063 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4064 if (status < 0)
4065 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004066
4067
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004068 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4069 if (status < 0)
4070 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004071
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004072 /* Write SC parameter registers, set all AUTO flags in operation mode */
4073 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4074 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4075 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4076 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4077 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4078 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4079 0, transmissionParams, param1, 0, 0, 0);
4080 if (status < 0)
4081 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004082
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004083 if (!state->m_DRXK_A3_ROM_CODE)
4084 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4085error:
4086 if (status < 0)
4087 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004088
4089 return status;
4090}
4091
4092
4093/*============================================================================*/
4094
4095/**
4096* \brief Retreive lock status .
4097* \param demod Pointer to demodulator instance.
4098* \param lockStat Pointer to lock status structure.
4099* \return DRXStatus_t.
4100*
4101*/
4102static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4103{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004104 int status;
4105 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4106 OFDM_SC_RA_RAM_LOCK_FEC__M);
4107 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4108 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004109
Oliver Endrissebc7de22011-07-03 13:49:44 -03004110 u16 ScRaRamLock = 0;
4111 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004112
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004113 dprintk(1, "\n");
4114
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004115 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004116 /* driver 0.9.0 */
4117 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004118 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004119 if (status < 0)
4120 goto end;
4121 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4122 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004123
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004124 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004125 if (status < 0)
4126 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004127
Oliver Endrissebc7de22011-07-03 13:49:44 -03004128 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4129 *pLockStatus = MPEG_LOCK;
4130 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4131 *pLockStatus = FEC_LOCK;
4132 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4133 *pLockStatus = DEMOD_LOCK;
4134 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4135 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004136end:
4137 if (status < 0)
4138 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004139
Oliver Endrissebc7de22011-07-03 13:49:44 -03004140 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004141}
4142
Oliver Endrissebc7de22011-07-03 13:49:44 -03004143static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004144{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004145 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004146 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004147
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004148 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004149 status = CtrlPowerMode(state, &powerMode);
4150 if (status < 0)
4151 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004152
Oliver Endrissebc7de22011-07-03 13:49:44 -03004153 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004154}
4155
4156
Oliver Endrissebc7de22011-07-03 13:49:44 -03004157/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004158static int PowerDownQAM(struct drxk_state *state)
4159{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004160 u16 data = 0;
4161 u16 cmdResult;
4162 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004163
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004164 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004165 status = read16(state, SCU_COMM_EXEC__A, &data);
4166 if (status < 0)
4167 goto error;
4168 if (data == SCU_COMM_EXEC_ACTIVE) {
4169 /*
4170 STOP demodulator
4171 QAM and HW blocks
4172 */
4173 /* stop all comstate->m_exec */
4174 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004175 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004176 goto error;
4177 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 -03004178 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004179 goto error;
4180 }
4181 /* powerdown AFE */
4182 status = SetIqmAf(state, false);
4183
4184error:
4185 if (status < 0)
4186 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004187
Oliver Endrissebc7de22011-07-03 13:49:44 -03004188 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004189}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004190
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004191/*============================================================================*/
4192
4193/**
4194* \brief Setup of the QAM Measurement intervals for signal quality
4195* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004196* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004197* \return DRXStatus_t.
4198*
4199* NOTE:
4200* Take into account that for certain settings the errorcounters can overflow.
4201* The implementation does not check this.
4202*
4203*/
4204static int SetQAMMeasurement(struct drxk_state *state,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004205 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004206 u32 symbolRate)
4207{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004208 u32 fecBitsDesired = 0; /* BER accounting period */
4209 u32 fecRsPeriodTotal = 0; /* Total period */
4210 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4211 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004212 int status = 0;
4213
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004214 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004215
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004216 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004217 /* fecBitsDesired = symbolRate [kHz] *
4218 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004219 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004220 SyncLoss (== 1) *
4221 ViterbiLoss (==1)
4222 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004223 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004224 case DRX_CONSTELLATION_QAM16:
4225 fecBitsDesired = 4 * symbolRate;
4226 break;
4227 case DRX_CONSTELLATION_QAM32:
4228 fecBitsDesired = 5 * symbolRate;
4229 break;
4230 case DRX_CONSTELLATION_QAM64:
4231 fecBitsDesired = 6 * symbolRate;
4232 break;
4233 case DRX_CONSTELLATION_QAM128:
4234 fecBitsDesired = 7 * symbolRate;
4235 break;
4236 case DRX_CONSTELLATION_QAM256:
4237 fecBitsDesired = 8 * symbolRate;
4238 break;
4239 default:
4240 status = -EINVAL;
4241 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004242 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004243 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004244
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004245 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4246 fecBitsDesired *= 500; /* meas. period [ms] */
4247
4248 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4249 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4250 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4251
4252 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4253 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4254 if (fecRsPrescale == 0) {
4255 /* Divide by zero (though impossible) */
4256 status = -EINVAL;
4257 if (status < 0)
4258 goto error;
4259 }
4260 fecRsPeriod =
4261 ((u16) fecRsPeriodTotal +
4262 (fecRsPrescale >> 1)) / fecRsPrescale;
4263
4264 /* write corresponding registers */
4265 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4266 if (status < 0)
4267 goto error;
4268 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4269 if (status < 0)
4270 goto error;
4271 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4272error:
4273 if (status < 0)
4274 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004275 return status;
4276}
4277
Oliver Endrissebc7de22011-07-03 13:49:44 -03004278static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004279{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004280 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004281
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004282 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004283 /* QAM Equalizer Setup */
4284 /* Equalizer */
4285 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4286 if (status < 0)
4287 goto error;
4288 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4289 if (status < 0)
4290 goto error;
4291 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4292 if (status < 0)
4293 goto error;
4294 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4295 if (status < 0)
4296 goto error;
4297 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4298 if (status < 0)
4299 goto error;
4300 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4301 if (status < 0)
4302 goto error;
4303 /* Decision Feedback Equalizer */
4304 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4305 if (status < 0)
4306 goto error;
4307 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4308 if (status < 0)
4309 goto error;
4310 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4311 if (status < 0)
4312 goto error;
4313 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4314 if (status < 0)
4315 goto error;
4316 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4317 if (status < 0)
4318 goto error;
4319 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4320 if (status < 0)
4321 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004322
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004323 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4324 if (status < 0)
4325 goto error;
4326 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4327 if (status < 0)
4328 goto error;
4329 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4330 if (status < 0)
4331 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004332
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004333 /* QAM Slicer Settings */
4334 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4335 if (status < 0)
4336 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004337
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004338 /* QAM Loop Controller Coeficients */
4339 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4340 if (status < 0)
4341 goto error;
4342 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4343 if (status < 0)
4344 goto error;
4345 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4346 if (status < 0)
4347 goto error;
4348 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4349 if (status < 0)
4350 goto error;
4351 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4352 if (status < 0)
4353 goto error;
4354 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4355 if (status < 0)
4356 goto error;
4357 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4358 if (status < 0)
4359 goto error;
4360 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4361 if (status < 0)
4362 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004363
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004364 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4365 if (status < 0)
4366 goto error;
4367 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4368 if (status < 0)
4369 goto error;
4370 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4371 if (status < 0)
4372 goto error;
4373 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4374 if (status < 0)
4375 goto error;
4376 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4377 if (status < 0)
4378 goto error;
4379 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4380 if (status < 0)
4381 goto error;
4382 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4383 if (status < 0)
4384 goto error;
4385 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4386 if (status < 0)
4387 goto error;
4388 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4389 if (status < 0)
4390 goto error;
4391 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4392 if (status < 0)
4393 goto error;
4394 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4395 if (status < 0)
4396 goto error;
4397 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4398 if (status < 0)
4399 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004400
4401
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004402 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004403
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004404 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4405 if (status < 0)
4406 goto error;
4407 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4408 if (status < 0)
4409 goto error;
4410 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4411 if (status < 0)
4412 goto error;
4413 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4414 if (status < 0)
4415 goto error;
4416 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4417 if (status < 0)
4418 goto error;
4419 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4420 if (status < 0)
4421 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004422
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004423 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4424 if (status < 0)
4425 goto error;
4426 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4427 if (status < 0)
4428 goto error;
4429 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4430 if (status < 0)
4431 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004432
4433
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004434 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004435
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004436 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4437 if (status < 0)
4438 goto error;
4439 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4440 if (status < 0)
4441 goto error;
4442 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4443 if (status < 0)
4444 goto error;
4445 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4446 if (status < 0)
4447 goto error;
4448 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4449 if (status < 0)
4450 goto error;
4451 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4452 if (status < 0)
4453 goto error;
4454 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4455 if (status < 0)
4456 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004457
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004458error:
4459 if (status < 0)
4460 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004461 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004462}
4463
4464/*============================================================================*/
4465
4466/**
4467* \brief QAM32 specific setup
4468* \param demod instance of demod.
4469* \return DRXStatus_t.
4470*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004471static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004472{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004473 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004474
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004475 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004476
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004477 /* QAM Equalizer Setup */
4478 /* Equalizer */
4479 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4480 if (status < 0)
4481 goto error;
4482 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4483 if (status < 0)
4484 goto error;
4485 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4486 if (status < 0)
4487 goto error;
4488 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4489 if (status < 0)
4490 goto error;
4491 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4492 if (status < 0)
4493 goto error;
4494 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4495 if (status < 0)
4496 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004497
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004498 /* Decision Feedback Equalizer */
4499 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4500 if (status < 0)
4501 goto error;
4502 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4503 if (status < 0)
4504 goto error;
4505 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4506 if (status < 0)
4507 goto error;
4508 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4509 if (status < 0)
4510 goto error;
4511 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4512 if (status < 0)
4513 goto error;
4514 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4515 if (status < 0)
4516 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004517
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004518 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4519 if (status < 0)
4520 goto error;
4521 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4522 if (status < 0)
4523 goto error;
4524 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4525 if (status < 0)
4526 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004527
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004528 /* QAM Slicer Settings */
4529
4530 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4531 if (status < 0)
4532 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004533
4534
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004535 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004536
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004537 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4538 if (status < 0)
4539 goto error;
4540 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4541 if (status < 0)
4542 goto error;
4543 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4544 if (status < 0)
4545 goto error;
4546 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4547 if (status < 0)
4548 goto error;
4549 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4550 if (status < 0)
4551 goto error;
4552 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4553 if (status < 0)
4554 goto error;
4555 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4556 if (status < 0)
4557 goto error;
4558 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4559 if (status < 0)
4560 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004561
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004562 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4563 if (status < 0)
4564 goto error;
4565 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4566 if (status < 0)
4567 goto error;
4568 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4569 if (status < 0)
4570 goto error;
4571 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4572 if (status < 0)
4573 goto error;
4574 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4575 if (status < 0)
4576 goto error;
4577 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4578 if (status < 0)
4579 goto error;
4580 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4581 if (status < 0)
4582 goto error;
4583 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4584 if (status < 0)
4585 goto error;
4586 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4587 if (status < 0)
4588 goto error;
4589 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4590 if (status < 0)
4591 goto error;
4592 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4593 if (status < 0)
4594 goto error;
4595 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4596 if (status < 0)
4597 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004598
4599
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004600 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004601
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004602 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4603 if (status < 0)
4604 goto error;
4605 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4606 if (status < 0)
4607 goto error;
4608 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4609 if (status < 0)
4610 goto error;
4611 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4612 if (status < 0)
4613 goto error;
4614 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4615 if (status < 0)
4616 goto error;
4617 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4618 if (status < 0)
4619 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004620
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004621 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4622 if (status < 0)
4623 goto error;
4624 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4625 if (status < 0)
4626 goto error;
4627 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4628 if (status < 0)
4629 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004630
4631
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004632 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004633
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004634 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4635 if (status < 0)
4636 goto error;
4637 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4638 if (status < 0)
4639 goto error;
4640 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4641 if (status < 0)
4642 goto error;
4643 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4644 if (status < 0)
4645 goto error;
4646 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4647 if (status < 0)
4648 goto error;
4649 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4650 if (status < 0)
4651 goto error;
4652 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4653error:
4654 if (status < 0)
4655 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004656 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004657}
4658
4659/*============================================================================*/
4660
4661/**
4662* \brief QAM64 specific setup
4663* \param demod instance of demod.
4664* \return DRXStatus_t.
4665*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004666static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004667{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004668 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004669
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004670 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004671 /* QAM Equalizer Setup */
4672 /* Equalizer */
4673 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4674 if (status < 0)
4675 goto error;
4676 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4677 if (status < 0)
4678 goto error;
4679 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4680 if (status < 0)
4681 goto error;
4682 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4683 if (status < 0)
4684 goto error;
4685 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4686 if (status < 0)
4687 goto error;
4688 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4689 if (status < 0)
4690 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004691
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004692 /* Decision Feedback Equalizer */
4693 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4694 if (status < 0)
4695 goto error;
4696 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4697 if (status < 0)
4698 goto error;
4699 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4700 if (status < 0)
4701 goto error;
4702 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4703 if (status < 0)
4704 goto error;
4705 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4706 if (status < 0)
4707 goto error;
4708 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4709 if (status < 0)
4710 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004711
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004712 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4713 if (status < 0)
4714 goto error;
4715 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4716 if (status < 0)
4717 goto error;
4718 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4719 if (status < 0)
4720 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004721
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004722 /* QAM Slicer Settings */
4723 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4724 if (status < 0)
4725 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004726
4727
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004728 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004729
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004730 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4731 if (status < 0)
4732 goto error;
4733 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4734 if (status < 0)
4735 goto error;
4736 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4737 if (status < 0)
4738 goto error;
4739 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4740 if (status < 0)
4741 goto error;
4742 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4743 if (status < 0)
4744 goto error;
4745 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4746 if (status < 0)
4747 goto error;
4748 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4749 if (status < 0)
4750 goto error;
4751 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4752 if (status < 0)
4753 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004754
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004755 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4756 if (status < 0)
4757 goto error;
4758 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4759 if (status < 0)
4760 goto error;
4761 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4762 if (status < 0)
4763 goto error;
4764 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4765 if (status < 0)
4766 goto error;
4767 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4768 if (status < 0)
4769 goto error;
4770 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4771 if (status < 0)
4772 goto error;
4773 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4774 if (status < 0)
4775 goto error;
4776 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4777 if (status < 0)
4778 goto error;
4779 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4780 if (status < 0)
4781 goto error;
4782 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4783 if (status < 0)
4784 goto error;
4785 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4786 if (status < 0)
4787 goto error;
4788 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4789 if (status < 0)
4790 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004791
4792
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004793 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004794
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004795 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4796 if (status < 0)
4797 goto error;
4798 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4799 if (status < 0)
4800 goto error;
4801 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4802 if (status < 0)
4803 goto error;
4804 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4805 if (status < 0)
4806 goto error;
4807 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4808 if (status < 0)
4809 goto error;
4810 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4811 if (status < 0)
4812 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004813
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004814 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4815 if (status < 0)
4816 goto error;
4817 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4818 if (status < 0)
4819 goto error;
4820 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4821 if (status < 0)
4822 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004823
4824
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004825 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004826
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004827 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4828 if (status < 0)
4829 goto error;
4830 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4831 if (status < 0)
4832 goto error;
4833 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4834 if (status < 0)
4835 goto error;
4836 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4837 if (status < 0)
4838 goto error;
4839 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4840 if (status < 0)
4841 goto error;
4842 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4843 if (status < 0)
4844 goto error;
4845 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4846error:
4847 if (status < 0)
4848 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004849
Oliver Endrissebc7de22011-07-03 13:49:44 -03004850 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004851}
4852
4853/*============================================================================*/
4854
4855/**
4856* \brief QAM128 specific setup
4857* \param demod: instance of demod.
4858* \return DRXStatus_t.
4859*/
4860static int SetQAM128(struct drxk_state *state)
4861{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004862 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004863
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004864 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004865 /* QAM Equalizer Setup */
4866 /* Equalizer */
4867 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4868 if (status < 0)
4869 goto error;
4870 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4871 if (status < 0)
4872 goto error;
4873 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4874 if (status < 0)
4875 goto error;
4876 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4877 if (status < 0)
4878 goto error;
4879 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4880 if (status < 0)
4881 goto error;
4882 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4883 if (status < 0)
4884 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004885
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004886 /* Decision Feedback Equalizer */
4887 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4888 if (status < 0)
4889 goto error;
4890 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4891 if (status < 0)
4892 goto error;
4893 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4894 if (status < 0)
4895 goto error;
4896 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4897 if (status < 0)
4898 goto error;
4899 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4900 if (status < 0)
4901 goto error;
4902 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4903 if (status < 0)
4904 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004905
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004906 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4907 if (status < 0)
4908 goto error;
4909 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4910 if (status < 0)
4911 goto error;
4912 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4913 if (status < 0)
4914 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004915
4916
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004917 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004919 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4920 if (status < 0)
4921 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004922
4923
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004924 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004925
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004926 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4927 if (status < 0)
4928 goto error;
4929 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4930 if (status < 0)
4931 goto error;
4932 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4933 if (status < 0)
4934 goto error;
4935 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4936 if (status < 0)
4937 goto error;
4938 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4939 if (status < 0)
4940 goto error;
4941 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4942 if (status < 0)
4943 goto error;
4944 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4945 if (status < 0)
4946 goto error;
4947 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4948 if (status < 0)
4949 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004950
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004951 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4952 if (status < 0)
4953 goto error;
4954 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4955 if (status < 0)
4956 goto error;
4957 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4958 if (status < 0)
4959 goto error;
4960 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4961 if (status < 0)
4962 goto error;
4963 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4964 if (status < 0)
4965 goto error;
4966 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4967 if (status < 0)
4968 goto error;
4969 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4970 if (status < 0)
4971 goto error;
4972 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4973 if (status < 0)
4974 goto error;
4975 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4976 if (status < 0)
4977 goto error;
4978 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4979 if (status < 0)
4980 goto error;
4981 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4982 if (status < 0)
4983 goto error;
4984 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4985 if (status < 0)
4986 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004987
4988
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004989 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004990
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004991 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4992 if (status < 0)
4993 goto error;
4994 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4995 if (status < 0)
4996 goto error;
4997 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4998 if (status < 0)
4999 goto error;
5000 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5001 if (status < 0)
5002 goto error;
5003 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
5004 if (status < 0)
5005 goto error;
5006 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5007 if (status < 0)
5008 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005009
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005010 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5011 if (status < 0)
5012 goto error;
5013 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5014 if (status < 0)
5015 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005016
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005017 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5018 if (status < 0)
5019 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005020
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005021 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005022
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005023 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5024 if (status < 0)
5025 goto error;
5026 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5027 if (status < 0)
5028 goto error;
5029 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5030 if (status < 0)
5031 goto error;
5032 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5033 if (status < 0)
5034 goto error;
5035 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5036 if (status < 0)
5037 goto error;
5038 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5039 if (status < 0)
5040 goto error;
5041 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5042error:
5043 if (status < 0)
5044 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005045
Oliver Endrissebc7de22011-07-03 13:49:44 -03005046 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005047}
5048
5049/*============================================================================*/
5050
5051/**
5052* \brief QAM256 specific setup
5053* \param demod: instance of demod.
5054* \return DRXStatus_t.
5055*/
5056static int SetQAM256(struct drxk_state *state)
5057{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005058 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005059
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005060 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005061 /* QAM Equalizer Setup */
5062 /* Equalizer */
5063 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5064 if (status < 0)
5065 goto error;
5066 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5067 if (status < 0)
5068 goto error;
5069 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5070 if (status < 0)
5071 goto error;
5072 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5073 if (status < 0)
5074 goto error;
5075 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5076 if (status < 0)
5077 goto error;
5078 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5079 if (status < 0)
5080 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005081
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005082 /* Decision Feedback Equalizer */
5083 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5084 if (status < 0)
5085 goto error;
5086 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5087 if (status < 0)
5088 goto error;
5089 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5090 if (status < 0)
5091 goto error;
5092 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5093 if (status < 0)
5094 goto error;
5095 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5096 if (status < 0)
5097 goto error;
5098 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5099 if (status < 0)
5100 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005101
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005102 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5103 if (status < 0)
5104 goto error;
5105 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5106 if (status < 0)
5107 goto error;
5108 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5109 if (status < 0)
5110 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005111
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005112 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005113
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005114 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5115 if (status < 0)
5116 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005117
5118
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005119 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005120
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005121 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5122 if (status < 0)
5123 goto error;
5124 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5125 if (status < 0)
5126 goto error;
5127 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5128 if (status < 0)
5129 goto error;
5130 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5131 if (status < 0)
5132 goto error;
5133 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5134 if (status < 0)
5135 goto error;
5136 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5137 if (status < 0)
5138 goto error;
5139 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5140 if (status < 0)
5141 goto error;
5142 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5143 if (status < 0)
5144 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005145
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005146 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5147 if (status < 0)
5148 goto error;
5149 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5150 if (status < 0)
5151 goto error;
5152 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5153 if (status < 0)
5154 goto error;
5155 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5156 if (status < 0)
5157 goto error;
5158 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5159 if (status < 0)
5160 goto error;
5161 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5162 if (status < 0)
5163 goto error;
5164 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5165 if (status < 0)
5166 goto error;
5167 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5168 if (status < 0)
5169 goto error;
5170 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5171 if (status < 0)
5172 goto error;
5173 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5174 if (status < 0)
5175 goto error;
5176 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5177 if (status < 0)
5178 goto error;
5179 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5180 if (status < 0)
5181 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005182
5183
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005184 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005185
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005186 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5187 if (status < 0)
5188 goto error;
5189 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5190 if (status < 0)
5191 goto error;
5192 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5193 if (status < 0)
5194 goto error;
5195 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5196 if (status < 0)
5197 goto error;
5198 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5199 if (status < 0)
5200 goto error;
5201 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5202 if (status < 0)
5203 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005204
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005205 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5206 if (status < 0)
5207 goto error;
5208 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5209 if (status < 0)
5210 goto error;
5211 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5212 if (status < 0)
5213 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005214
5215
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005216 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005217
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005218 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5219 if (status < 0)
5220 goto error;
5221 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5222 if (status < 0)
5223 goto error;
5224 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5225 if (status < 0)
5226 goto error;
5227 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5228 if (status < 0)
5229 goto error;
5230 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5231 if (status < 0)
5232 goto error;
5233 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5234 if (status < 0)
5235 goto error;
5236 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5237error:
5238 if (status < 0)
5239 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005240 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005241}
5242
5243
5244/*============================================================================*/
5245/**
5246* \brief Reset QAM block.
5247* \param demod: instance of demod.
5248* \param channel: pointer to channel data.
5249* \return DRXStatus_t.
5250*/
5251static int QAMResetQAM(struct drxk_state *state)
5252{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005253 int status;
5254 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005255
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005256 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005257 /* Stop QAM comstate->m_exec */
5258 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5259 if (status < 0)
5260 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005261
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005262 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5263error:
5264 if (status < 0)
5265 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005266 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005267}
5268
5269/*============================================================================*/
5270
5271/**
5272* \brief Set QAM symbolrate.
5273* \param demod: instance of demod.
5274* \param channel: pointer to channel data.
5275* \return DRXStatus_t.
5276*/
5277static int QAMSetSymbolrate(struct drxk_state *state)
5278{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005279 u32 adcFrequency = 0;
5280 u32 symbFreq = 0;
5281 u32 iqmRcRate = 0;
5282 u16 ratesel = 0;
5283 u32 lcSymbRate = 0;
5284 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005285
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005286 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005287 /* Select & calculate correct IQM rate */
5288 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5289 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005290 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5291 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005292 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005293 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005294 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005295 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005296 ratesel = 1;
5297 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5298 if (status < 0)
5299 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005300
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005301 /*
5302 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5303 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005304 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005305 if (symbFreq == 0) {
5306 /* Divide by zero */
5307 status = -EINVAL;
5308 goto error;
5309 }
5310 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5311 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5312 (1 << 23);
5313 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5314 if (status < 0)
5315 goto error;
5316 state->m_iqmRcRate = iqmRcRate;
5317 /*
5318 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5319 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005320 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005321 if (adcFrequency == 0) {
5322 /* Divide by zero */
5323 status = -EINVAL;
5324 goto error;
5325 }
5326 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5327 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5328 16);
5329 if (lcSymbRate > 511)
5330 lcSymbRate = 511;
5331 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005332
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005333error:
5334 if (status < 0)
5335 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005336 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005337}
5338
5339/*============================================================================*/
5340
5341/**
5342* \brief Get QAM lock status.
5343* \param demod: instance of demod.
5344* \param channel: pointer to channel data.
5345* \return DRXStatus_t.
5346*/
5347
5348static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5349{
5350 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005351 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005352
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005353 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005354 *pLockStatus = NOT_LOCKED;
5355 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005356 SCU_RAM_COMMAND_STANDARD_QAM |
5357 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5358 Result);
5359 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005360 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005361
5362 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005363 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005364 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005365 /* 0x4000 DEMOD LOCKED */
5366 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005367 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005368 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5369 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005370 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005371 /* 0xC000 NEVER LOCKED */
5372 /* (system will never be able to lock to the signal) */
5373 /* TODO: check this, intermediate & standard specific lock states are not
5374 taken into account here */
5375 *pLockStatus = NEVER_LOCK;
5376 }
5377 return status;
5378}
5379
5380#define QAM_MIRROR__M 0x03
5381#define QAM_MIRROR_NORMAL 0x00
5382#define QAM_MIRRORED 0x01
5383#define QAM_MIRROR_AUTO_ON 0x02
5384#define QAM_LOCKRANGE__M 0x10
5385#define QAM_LOCKRANGE_NORMAL 0x10
5386
Oliver Endrissebc7de22011-07-03 13:49:44 -03005387static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5388 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005389{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005390 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005391 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5392 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005393
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005394 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005395 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005396 * STEP 1: reset demodulator
5397 * resets FEC DI and FEC RS
5398 * resets QAM block
5399 * resets SCU variables
5400 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005401 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005402 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005403 goto error;
5404 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5405 if (status < 0)
5406 goto error;
5407 status = QAMResetQAM(state);
5408 if (status < 0)
5409 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005410
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005411 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005412 * STEP 2: configure demodulator
5413 * -set params; resets IQM,QAM,FEC HW; initializes some
5414 * SCU variables
5415 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005416 status = QAMSetSymbolrate(state);
5417 if (status < 0)
5418 goto error;
5419
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005420 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005421 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005422 case QAM_256:
5423 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5424 break;
5425 case QAM_AUTO:
5426 case QAM_64:
5427 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5428 break;
5429 case QAM_16:
5430 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5431 break;
5432 case QAM_32:
5433 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5434 break;
5435 case QAM_128:
5436 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5437 break;
5438 default:
5439 status = -EINVAL;
5440 break;
5441 }
5442 if (status < 0)
5443 goto error;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005444 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005445 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005446 if (state->m_OperationMode == OM_QAM_ITU_C)
5447 setParamParameters[2] = QAM_TOP_ANNEX_C;
5448 else
5449 setParamParameters[2] = QAM_TOP_ANNEX_A;
5450 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5451 /* Env parameters */
5452 /* check for LOCKRANGE Extented */
5453 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005454
5455 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 -03005456 if (status < 0) {
5457 /* Fall-back to the simpler call */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005458 if (state->m_OperationMode == OM_QAM_ITU_C)
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005459 setParamParameters[0] = QAM_TOP_ANNEX_C;
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005460 else
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005461 setParamParameters[0] = QAM_TOP_ANNEX_A;
5462 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult);
5463 if (status < 0)
5464 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005465
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005466 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005467 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005468 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
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005473 /*
5474 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005475 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005476 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005477#if 0
5478 status = SetFrequency(channel, tunerFreqOffset));
5479 if (status < 0)
5480 goto error;
5481#endif
5482 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5483 if (status < 0)
5484 goto error;
5485
5486 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005487 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005488 if (status < 0)
5489 goto error;
5490
5491 /* Reset default values */
5492 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5493 if (status < 0)
5494 goto error;
5495 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5496 if (status < 0)
5497 goto error;
5498
5499 /* Reset default LC values */
5500 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5501 if (status < 0)
5502 goto error;
5503 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5504 if (status < 0)
5505 goto error;
5506 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5507 if (status < 0)
5508 goto error;
5509 status = write16(state, QAM_LC_MODE__A, 7);
5510 if (status < 0)
5511 goto error;
5512
5513 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5514 if (status < 0)
5515 goto error;
5516 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5517 if (status < 0)
5518 goto error;
5519 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5520 if (status < 0)
5521 goto error;
5522 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5523 if (status < 0)
5524 goto error;
5525 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5526 if (status < 0)
5527 goto error;
5528 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5529 if (status < 0)
5530 goto error;
5531 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5532 if (status < 0)
5533 goto error;
5534 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5535 if (status < 0)
5536 goto error;
5537 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5538 if (status < 0)
5539 goto error;
5540 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5541 if (status < 0)
5542 goto error;
5543 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5544 if (status < 0)
5545 goto error;
5546 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5547 if (status < 0)
5548 goto error;
5549 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5550 if (status < 0)
5551 goto error;
5552 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5553 if (status < 0)
5554 goto error;
5555 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5556 if (status < 0)
5557 goto error;
5558
5559 /* Mirroring, QAM-block starting point not inverted */
5560 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5561 if (status < 0)
5562 goto error;
5563
5564 /* Halt SCU to enable safe non-atomic accesses */
5565 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5566 if (status < 0)
5567 goto error;
5568
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005569 /* STEP 4: modulation specific setup */
5570 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005571 case QAM_16:
5572 status = SetQAM16(state);
5573 break;
5574 case QAM_32:
5575 status = SetQAM32(state);
5576 break;
5577 case QAM_AUTO:
5578 case QAM_64:
5579 status = SetQAM64(state);
5580 break;
5581 case QAM_128:
5582 status = SetQAM128(state);
5583 break;
5584 case QAM_256:
5585 status = SetQAM256(state);
5586 break;
5587 default:
5588 status = -EINVAL;
5589 break;
5590 }
5591 if (status < 0)
5592 goto error;
5593
5594 /* Activate SCU to enable SCU commands */
5595 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5596 if (status < 0)
5597 goto error;
5598
5599 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005600 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005601 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5602 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5603 if (status < 0)
5604 goto error;
5605
5606 /* Start processes */
5607 status = MPEGTSStart(state);
5608 if (status < 0)
5609 goto error;
5610 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5611 if (status < 0)
5612 goto error;
5613 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5614 if (status < 0)
5615 goto error;
5616 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5617 if (status < 0)
5618 goto error;
5619
5620 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5621 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5622 if (status < 0)
5623 goto error;
5624
5625 /* update global DRXK data container */
5626/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5627
5628error:
5629 if (status < 0)
5630 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005631 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005632}
5633
Oliver Endrissebc7de22011-07-03 13:49:44 -03005634static int SetQAMStandard(struct drxk_state *state,
5635 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005636{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005637 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005638#ifdef DRXK_QAM_TAPS
5639#define DRXK_QAMA_TAPS_SELECT
5640#include "drxk_filters.h"
5641#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005642#endif
5643
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005644 dprintk(1, "\n");
5645
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005646 /* added antenna switch */
5647 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005648
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005649 /* Ensure correct power-up mode */
5650 status = PowerUpQAM(state);
5651 if (status < 0)
5652 goto error;
5653 /* Reset QAM block */
5654 status = QAMResetQAM(state);
5655 if (status < 0)
5656 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005657
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005658 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005659
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005660 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5661 if (status < 0)
5662 goto error;
5663 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5664 if (status < 0)
5665 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005666
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005667 /* Upload IQM Channel Filter settings by
5668 boot loader from ROM table */
5669 switch (oMode) {
5670 case OM_QAM_ITU_A:
5671 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5672 break;
5673 case OM_QAM_ITU_C:
5674 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 -03005675 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005676 goto error;
5677 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5678 break;
5679 default:
5680 status = -EINVAL;
5681 }
5682 if (status < 0)
5683 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005684
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005685 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5686 if (status < 0)
5687 goto error;
5688 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5689 if (status < 0)
5690 goto error;
5691 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5692 if (status < 0)
5693 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005694
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005695 status = write16(state, IQM_RC_STRETCH__A, 21);
5696 if (status < 0)
5697 goto error;
5698 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5699 if (status < 0)
5700 goto error;
5701 status = write16(state, IQM_AF_CLP_TH__A, 448);
5702 if (status < 0)
5703 goto error;
5704 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5705 if (status < 0)
5706 goto error;
5707 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5708 if (status < 0)
5709 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005710
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005711 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5712 if (status < 0)
5713 goto error;
5714 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5715 if (status < 0)
5716 goto error;
5717 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5718 if (status < 0)
5719 goto error;
5720 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5721 if (status < 0)
5722 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005723
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005724 /* IQM Impulse Noise Processing Unit */
5725 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5726 if (status < 0)
5727 goto error;
5728 status = write16(state, IQM_CF_DATATH__A, 1000);
5729 if (status < 0)
5730 goto error;
5731 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5732 if (status < 0)
5733 goto error;
5734 status = write16(state, IQM_CF_DET_LCT__A, 0);
5735 if (status < 0)
5736 goto error;
5737 status = write16(state, IQM_CF_WND_LEN__A, 1);
5738 if (status < 0)
5739 goto error;
5740 status = write16(state, IQM_CF_PKDTH__A, 1);
5741 if (status < 0)
5742 goto error;
5743 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5744 if (status < 0)
5745 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005746
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005747 /* turn on IQMAF. Must be done before setAgc**() */
5748 status = SetIqmAf(state, true);
5749 if (status < 0)
5750 goto error;
5751 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5752 if (status < 0)
5753 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005754
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005755 /* IQM will not be reset from here, sync ADC and update/init AGC */
5756 status = ADCSynchronization(state);
5757 if (status < 0)
5758 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005759
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005760 /* Set the FSM step period */
5761 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5762 if (status < 0)
5763 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005764
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005765 /* Halt SCU to enable safe non-atomic accesses */
5766 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5767 if (status < 0)
5768 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005769
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005770 /* No more resets of the IQM, current standard correctly set =>
5771 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005772
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005773 status = InitAGC(state, true);
5774 if (status < 0)
5775 goto error;
5776 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5777 if (status < 0)
5778 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005779
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005780 /* Configure AGC's */
5781 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5782 if (status < 0)
5783 goto error;
5784 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5785 if (status < 0)
5786 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005787
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005788 /* Activate SCU to enable SCU commands */
5789 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5790error:
5791 if (status < 0)
5792 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005793 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005794}
5795
5796static int WriteGPIO(struct drxk_state *state)
5797{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005798 int status;
5799 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005800
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005801 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005802 /* stop lock indicator process */
5803 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5804 if (status < 0)
5805 goto error;
5806
5807 /* Write magic word to enable pdr reg write */
5808 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5809 if (status < 0)
5810 goto error;
5811
5812 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005813 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5814 /* write to io pad configuration register - output mode */
5815 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5816 if (status < 0)
5817 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005818
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005819 /* use corresponding bit in io data output registar */
5820 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5821 if (status < 0)
5822 goto error;
5823 if ((state->m_GPIO & 0x0001) == 0)
5824 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5825 else
5826 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5827 /* write back to io data output register */
5828 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5829 if (status < 0)
5830 goto error;
5831 }
5832 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5833 /* write to io pad configuration register - output mode */
5834 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5835 if (status < 0)
5836 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005837
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005838 /* use corresponding bit in io data output registar */
5839 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5840 if (status < 0)
5841 goto error;
5842 if ((state->m_GPIO & 0x0002) == 0)
5843 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5844 else
5845 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5846 /* write back to io data output register */
5847 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5848 if (status < 0)
5849 goto error;
5850 }
5851 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5852 /* write to io pad configuration register - output mode */
5853 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5854 if (status < 0)
5855 goto error;
5856
5857 /* use corresponding bit in io data output registar */
5858 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5859 if (status < 0)
5860 goto error;
5861 if ((state->m_GPIO & 0x0004) == 0)
5862 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5863 else
5864 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5865 /* write back to io data output register */
5866 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5867 if (status < 0)
5868 goto error;
5869 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005870 }
5871 /* Write magic word to disable pdr reg write */
5872 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5873error:
5874 if (status < 0)
5875 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005876 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005877}
5878
5879static int SwitchAntennaToQAM(struct drxk_state *state)
5880{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005881 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005882 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005883
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005884 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005885
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005886 if (!state->antenna_gpio)
5887 return 0;
5888
5889 gpio_state = state->m_GPIO & state->antenna_gpio;
5890
5891 if (state->antenna_dvbt ^ gpio_state) {
5892 /* Antenna is on DVB-T mode. Switch */
5893 if (state->antenna_dvbt)
5894 state->m_GPIO &= ~state->antenna_gpio;
5895 else
5896 state->m_GPIO |= state->antenna_gpio;
5897 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005898 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005899 if (status < 0)
5900 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005901 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005902}
5903
5904static int SwitchAntennaToDVBT(struct drxk_state *state)
5905{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005906 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005907 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005908
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005909 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005910
5911 if (!state->antenna_gpio)
5912 return 0;
5913
5914 gpio_state = state->m_GPIO & state->antenna_gpio;
5915
5916 if (!(state->antenna_dvbt ^ gpio_state)) {
5917 /* Antenna is on DVB-C mode. Switch */
5918 if (state->antenna_dvbt)
5919 state->m_GPIO |= state->antenna_gpio;
5920 else
5921 state->m_GPIO &= ~state->antenna_gpio;
5922 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005923 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005924 if (status < 0)
5925 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005926 return status;
5927}
5928
5929
5930static int PowerDownDevice(struct drxk_state *state)
5931{
5932 /* Power down to requested mode */
5933 /* Backup some register settings */
5934 /* Set pins with possible pull-ups connected to them in input mode */
5935 /* Analog power down */
5936 /* ADC power down */
5937 /* Power down device */
5938 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005939
5940 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005941 if (state->m_bPDownOpenBridge) {
5942 /* Open I2C bridge before power down of DRXK */
5943 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005944 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005945 goto error;
5946 }
5947 /* driver 0.9.0 */
5948 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005949 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005950 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005951
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005952 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5953 if (status < 0)
5954 goto error;
5955 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5956 if (status < 0)
5957 goto error;
5958 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5959 status = HI_CfgCommand(state);
5960error:
5961 if (status < 0)
5962 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5963
5964 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005965}
5966
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005967static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005968{
5969 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005970 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005971
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005972 dprintk(1, "\n");
5973
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005974 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5975 if (err < 0) {
5976 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005977 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005978 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005979 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005980 return err;
5981 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005982 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005983 release_firmware(fw);
5984 return err;
5985}
5986
5987static int init_drxk(struct drxk_state *state)
5988{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005989 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005990 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005991 u16 driverVersion;
5992
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005993 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005994 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005995 status = PowerUpDevice(state);
5996 if (status < 0)
5997 goto error;
5998 status = DRXX_Open(state);
5999 if (status < 0)
6000 goto error;
6001 /* Soft reset of OFDM-, sys- and osc-clockdomain */
6002 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);
6003 if (status < 0)
6004 goto error;
6005 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6006 if (status < 0)
6007 goto error;
6008 /* TODO is this needed, if yes how much delay in worst case scenario */
6009 msleep(1);
6010 state->m_DRXK_A3_PATCH_CODE = true;
6011 status = GetDeviceCapabilities(state);
6012 if (status < 0)
6013 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006014
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006015 /* Bridge delay, uses oscilator clock */
6016 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6017 /* SDA brdige delay */
6018 state->m_HICfgBridgeDelay =
6019 (u16) ((state->m_oscClockFreq / 1000) *
6020 HI_I2C_BRIDGE_DELAY) / 1000;
6021 /* Clipping */
6022 if (state->m_HICfgBridgeDelay >
6023 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006024 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006025 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6026 }
6027 /* SCL bridge delay, same as SDA for now */
6028 state->m_HICfgBridgeDelay +=
6029 state->m_HICfgBridgeDelay <<
6030 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006031
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006032 status = InitHI(state);
6033 if (status < 0)
6034 goto error;
6035 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006036#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006037 if (!(state->m_DRXK_A1_ROM_CODE)
6038 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006039#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006040 {
6041 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6042 if (status < 0)
6043 goto error;
6044 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006045
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006046 /* disable MPEG port */
6047 status = MPEGTSDisable(state);
6048 if (status < 0)
6049 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006050
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006051 /* Stop AUD and SCU */
6052 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6053 if (status < 0)
6054 goto error;
6055 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6056 if (status < 0)
6057 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006058
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006059 /* enable token-ring bus through OFDM block for possible ucode upload */
6060 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6061 if (status < 0)
6062 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006063
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006064 /* include boot loader section */
6065 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6066 if (status < 0)
6067 goto error;
6068 status = BLChainCmd(state, 0, 6, 100);
6069 if (status < 0)
6070 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006071
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006072 if (!state->microcode_name)
6073 load_microcode(state, "drxk_a3.mc");
6074 else
6075 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006076
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006077 /* disable token-ring bus through OFDM block for possible ucode upload */
6078 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6079 if (status < 0)
6080 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006081
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006082 /* Run SCU for a little while to initialize microcode version numbers */
6083 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6084 if (status < 0)
6085 goto error;
6086 status = DRXX_Open(state);
6087 if (status < 0)
6088 goto error;
6089 /* added for test */
6090 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006091
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006092 powerMode = DRXK_POWER_DOWN_OFDM;
6093 status = CtrlPowerMode(state, &powerMode);
6094 if (status < 0)
6095 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006096
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006097 /* Stamp driver version number in SCU data RAM in BCD code
6098 Done to enable field application engineers to retreive drxdriver version
6099 via I2C from SCU RAM.
6100 Not using SCU command interface for SCU register access since no
6101 microcode may be present.
6102 */
6103 driverVersion =
6104 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6105 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6106 ((DRXK_VERSION_MAJOR % 10) << 4) +
6107 (DRXK_VERSION_MINOR % 10);
6108 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6109 if (status < 0)
6110 goto error;
6111 driverVersion =
6112 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6113 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6114 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6115 (DRXK_VERSION_PATCH % 10);
6116 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6117 if (status < 0)
6118 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006119
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006120 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6121 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6122 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006123
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006124 /* Dirty fix of default values for ROM/PATCH microcode
6125 Dirty because this fix makes it impossible to setup suitable values
6126 before calling DRX_Open. This solution requires changes to RF AGC speed
6127 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006128
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006129 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006130
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006131 /* Reset driver debug flags to 0 */
6132 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6133 if (status < 0)
6134 goto error;
6135 /* driver 0.9.0 */
6136 /* Setup FEC OC:
6137 NOTE: No more full FEC resets allowed afterwards!! */
6138 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6139 if (status < 0)
6140 goto error;
6141 /* MPEGTS functions are still the same */
6142 status = MPEGTSDtoInit(state);
6143 if (status < 0)
6144 goto error;
6145 status = MPEGTSStop(state);
6146 if (status < 0)
6147 goto error;
6148 status = MPEGTSConfigurePolarity(state);
6149 if (status < 0)
6150 goto error;
6151 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6152 if (status < 0)
6153 goto error;
6154 /* added: configure GPIO */
6155 status = WriteGPIO(state);
6156 if (status < 0)
6157 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006158
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006159 state->m_DrxkState = DRXK_STOPPED;
6160
6161 if (state->m_bPowerDown) {
6162 status = PowerDownDevice(state);
6163 if (status < 0)
6164 goto error;
6165 state->m_DrxkState = DRXK_POWERED_DOWN;
6166 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006167 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006168 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006169error:
6170 if (status < 0)
6171 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006172
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006173 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006174}
6175
Oliver Endrissebc7de22011-07-03 13:49:44 -03006176static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006177{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006178 struct drxk_state *state = fe->demodulator_priv;
6179
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006180 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006181 kfree(state);
6182}
6183
Oliver Endrissebc7de22011-07-03 13:49:44 -03006184static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006185{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006186 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006187
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006188 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006189 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006190 return -EBUSY;
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02006191 if (state->m_itut_annex_c)
6192 SetOperationMode(state, OM_QAM_ITU_C);
6193 else
6194 SetOperationMode(state, OM_QAM_ITU_A);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006195 return 0;
6196}
6197
Oliver Endrissebc7de22011-07-03 13:49:44 -03006198static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006199{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006200 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006201
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006202 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006203 ShutDown(state);
6204 mutex_unlock(&state->ctlock);
6205 return 0;
6206}
6207
Oliver Endrissebc7de22011-07-03 13:49:44 -03006208static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006209{
6210 struct drxk_state *state = fe->demodulator_priv;
6211
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006212 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006213 return ConfigureI2CBridge(state, enable ? true : false);
6214}
6215
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006216static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006217{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006218 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
6219 u32 delsys = p->delivery_system;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006220 struct drxk_state *state = fe->demodulator_priv;
6221 u32 IF;
6222
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006223 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006224
6225 if (!fe->ops.tuner_ops.get_if_frequency) {
6226 printk(KERN_ERR
6227 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6228 return -EINVAL;
6229 }
6230
Mauro Carvalho Chehabfd66c452011-12-17 20:36:57 -03006231 switch (delsys) {
6232 case SYS_DVBC_ANNEX_A:
6233 state->m_itut_annex_c = false;
6234 break;
6235 case SYS_DVBC_ANNEX_C:
6236 state->m_itut_annex_c = true;
6237 break;
6238 default:
6239 return -EINVAL;
Mauro Carvalho Chehab2440f7a2011-11-11 20:26:03 -02006240 }
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006241
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006242 if (fe->ops.i2c_gate_ctrl)
6243 fe->ops.i2c_gate_ctrl(fe, 1);
6244 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006245 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006246 if (fe->ops.i2c_gate_ctrl)
6247 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006248 state->props = *p;
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006249 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006250 Start(state, 0, IF);
6251
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006252 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006253
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006254 return 0;
6255}
6256
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006257static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6258{
6259 struct drxk_state *state = fe->demodulator_priv;
6260 u32 stat;
6261
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006262 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006263 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006264 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006265 if (stat == MPEG_LOCK)
6266 *status |= 0x1f;
6267 if (stat == FEC_LOCK)
6268 *status |= 0x0f;
6269 if (stat == DEMOD_LOCK)
6270 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006271 return 0;
6272}
6273
6274static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6275{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006276 dprintk(1, "\n");
6277
Oliver Endrissebc7de22011-07-03 13:49:44 -03006278 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006279 return 0;
6280}
6281
Oliver Endrissebc7de22011-07-03 13:49:44 -03006282static int drxk_read_signal_strength(struct dvb_frontend *fe,
6283 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006284{
6285 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006286 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006287
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006288 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006289 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006290 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006291 return 0;
6292}
6293
6294static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6295{
6296 struct drxk_state *state = fe->demodulator_priv;
6297 s32 snr2;
6298
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006299 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006300 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006301 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006302 return 0;
6303}
6304
6305static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6306{
6307 struct drxk_state *state = fe->demodulator_priv;
6308 u16 err;
6309
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006310 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006311 DVBTQAMGetAccPktErr(state, &err);
6312 *ucblocks = (u32) err;
6313 return 0;
6314}
6315
Oliver Endrissebc7de22011-07-03 13:49:44 -03006316static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6317 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006318{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006319 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006320 sets->min_delay_ms = 3000;
6321 sets->max_drift = 0;
6322 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006323 return 0;
6324}
6325
Oliver Endrissebc7de22011-07-03 13:49:44 -03006326static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006327{
Mauro Carvalho Chehabc4c3a3d2011-07-14 22:23:18 -03006328 /*
6329 * There's nothing to release here, as the state struct
6330 * is already freed by drxk_c_release.
6331 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006332}
6333
Oliver Endrissebc7de22011-07-03 13:49:44 -03006334static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006335{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006336 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006337
6338 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006339 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006340 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006341 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006342 return 0;
6343}
6344
Oliver Endrissebc7de22011-07-03 13:49:44 -03006345static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006346{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006347 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006348
6349 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006350 mutex_unlock(&state->ctlock);
6351 return 0;
6352}
6353
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006354static struct dvb_frontend_ops drxk_c_ops = {
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006355 .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C },
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006356 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006357 .name = "DRXK DVB-C",
Oliver Endrissebc7de22011-07-03 13:49:44 -03006358 .frequency_stepsize = 62500,
6359 .frequency_min = 47000000,
6360 .frequency_max = 862000000,
6361 .symbol_rate_min = 870000,
6362 .symbol_rate_max = 11700000,
6363 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6364 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006365 .release = drxk_c_release,
6366 .init = drxk_c_init,
6367 .sleep = drxk_c_sleep,
6368 .i2c_gate_ctrl = drxk_gate_ctrl,
6369
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006370 .set_frontend = drxk_set_parameters,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006371 .get_tune_settings = drxk_c_get_tune_settings,
6372
6373 .read_status = drxk_read_status,
6374 .read_ber = drxk_read_ber,
6375 .read_signal_strength = drxk_read_signal_strength,
6376 .read_snr = drxk_read_snr,
6377 .read_ucblocks = drxk_read_ucblocks,
6378};
6379
6380static struct dvb_frontend_ops drxk_t_ops = {
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006381 .delsys = { SYS_DVBT },
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006382 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006383 .name = "DRXK DVB-T",
Oliver Endrissebc7de22011-07-03 13:49:44 -03006384 .frequency_min = 47125000,
6385 .frequency_max = 865000000,
6386 .frequency_stepsize = 166667,
6387 .frequency_tolerance = 0,
6388 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6389 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6390 FE_CAN_FEC_AUTO |
6391 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6392 FE_CAN_QAM_AUTO |
6393 FE_CAN_TRANSMISSION_MODE_AUTO |
6394 FE_CAN_GUARD_INTERVAL_AUTO |
6395 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006396 .release = drxk_t_release,
6397 .init = drxk_t_init,
6398 .sleep = drxk_t_sleep,
6399 .i2c_gate_ctrl = drxk_gate_ctrl,
6400
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006401 .set_frontend = drxk_set_parameters,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006402
6403 .read_status = drxk_read_status,
6404 .read_ber = drxk_read_ber,
6405 .read_signal_strength = drxk_read_signal_strength,
6406 .read_snr = drxk_read_snr,
6407 .read_ucblocks = drxk_read_ucblocks,
6408};
6409
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006410struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6411 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006412 struct dvb_frontend **fe_t)
6413{
6414 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006415 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006416
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006417 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006418 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006419 if (!state)
6420 return NULL;
6421
Oliver Endrissebc7de22011-07-03 13:49:44 -03006422 state->i2c = i2c;
6423 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006424 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006425 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006426 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006427 state->antenna_gpio = config->antenna_gpio;
6428 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006429 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006430
6431 /* NOTE: as more UIO bits will be used, add them to the mask */
6432 state->UIO_mask = config->antenna_gpio;
6433
6434 /* Default gpio to DVB-C */
6435 if (!state->antenna_dvbt && state->antenna_gpio)
6436 state->m_GPIO |= state->antenna_gpio;
6437 else
6438 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006439
6440 mutex_init(&state->mutex);
6441 mutex_init(&state->ctlock);
6442
Oliver Endrissebc7de22011-07-03 13:49:44 -03006443 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6444 sizeof(struct dvb_frontend_ops));
6445 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6446 sizeof(struct dvb_frontend_ops));
6447 state->c_frontend.demodulator_priv = state;
6448 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006449
6450 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006451 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006452 goto error;
6453 *fe_t = &state->t_frontend;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006454
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006455 return &state->c_frontend;
6456
6457error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006458 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006459 kfree(state);
6460 return NULL;
6461}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006462EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006463
6464MODULE_DESCRIPTION("DRX-K driver");
6465MODULE_AUTHOR("Ralph Metzler");
6466MODULE_LICENSE("GPL");