blob: f74a17641278db4eaafa79e8781620c757fa73ab [file] [log] [blame]
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001/*
2 * drxk_hard: DRX-K DVB-C/T demodulator driver
3 *
4 * Copyright (C) 2010-2011 Digital Devices GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/firmware.h>
30#include <linux/i2c.h>
31#include <linux/version.h>
32#include <asm/div64.h>
33
34#include "dvb_frontend.h"
35#include "drxk.h"
36#include "drxk_hard.h"
37
38static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
39static int PowerDownQAM(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030040static int SetDVBTStandard(struct drxk_state *state,
41 enum OperationMode oMode);
42static int SetQAMStandard(struct drxk_state *state,
43 enum OperationMode oMode);
44static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
Ralph Metzler43dd07f2011-07-03 13:42:18 -030045 s32 tunerFreqOffset);
Oliver Endrissebc7de22011-07-03 13:49:44 -030046static int SetDVBTStandard(struct drxk_state *state,
47 enum OperationMode oMode);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030048static int DVBTStart(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030049static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
50 s32 tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030051static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
52static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
53static int SwitchAntennaToQAM(struct drxk_state *state);
54static int SwitchAntennaToDVBT(struct drxk_state *state);
55
56static bool IsDVBT(struct drxk_state *state)
57{
58 return state->m_OperationMode == OM_DVBT;
59}
60
61static bool IsQAM(struct drxk_state *state)
62{
63 return state->m_OperationMode == OM_QAM_ITU_A ||
Oliver Endrissebc7de22011-07-03 13:49:44 -030064 state->m_OperationMode == OM_QAM_ITU_B ||
65 state->m_OperationMode == OM_QAM_ITU_C;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030066}
67
68bool IsA1WithPatchCode(struct drxk_state *state)
69{
70 return state->m_DRXK_A1_PATCH_CODE;
71}
72
73bool IsA1WithRomCode(struct drxk_state *state)
74{
75 return state->m_DRXK_A1_ROM_CODE;
76}
77
78#define NOA1ROM 0
79
Ralph Metzler43dd07f2011-07-03 13:42:18 -030080#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
81#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
82
83#define DEFAULT_MER_83 165
84#define DEFAULT_MER_93 250
85
86#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
87#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
88#endif
89
90#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
91#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
92#endif
93
94#ifndef DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH
95#define DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH (0x06)
96#endif
97
98#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
99#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
100
101#ifndef DRXK_KI_RAGC_ATV
102#define DRXK_KI_RAGC_ATV 4
103#endif
104#ifndef DRXK_KI_IAGC_ATV
105#define DRXK_KI_IAGC_ATV 6
106#endif
107#ifndef DRXK_KI_DAGC_ATV
108#define DRXK_KI_DAGC_ATV 7
109#endif
110
111#ifndef DRXK_KI_RAGC_QAM
112#define DRXK_KI_RAGC_QAM 3
113#endif
114#ifndef DRXK_KI_IAGC_QAM
115#define DRXK_KI_IAGC_QAM 4
116#endif
117#ifndef DRXK_KI_DAGC_QAM
118#define DRXK_KI_DAGC_QAM 7
119#endif
120#ifndef DRXK_KI_RAGC_DVBT
121#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
122#endif
123#ifndef DRXK_KI_IAGC_DVBT
124#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
125#endif
126#ifndef DRXK_KI_DAGC_DVBT
127#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
128#endif
129
130#ifndef DRXK_AGC_DAC_OFFSET
131#define DRXK_AGC_DAC_OFFSET (0x800)
132#endif
133
134#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
135#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
136#endif
137
138#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
139#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
140#endif
141
142#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
143#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
144#endif
145
146#ifndef DRXK_QAM_SYMBOLRATE_MAX
147#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
148#endif
149
150#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
151#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
152#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
153#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
154#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
155#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
156#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
157#define DRXK_BL_ROM_OFFSET_UCODE 0
158
159#define DRXK_BLC_TIMEOUT 100
160
161#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
162#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
163
164#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
165
166#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
167#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
168#endif
169
170#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
171#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
172#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
173#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
174#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
175
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300176static unsigned int debug;
177module_param(debug, int, 0644);
178MODULE_PARM_DESC(debug, "enable debug messages");
179
180#define dprintk(level, fmt, arg...) do { \
181if (debug >= level) \
182 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
183} while (0)
184
185
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300186static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300187{
188 u64 tmp64;
189
Oliver Endrissebc7de22011-07-03 13:49:44 -0300190 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300191 do_div(tmp64, c);
192
193 return (u32) tmp64;
194}
195
196inline u32 Frac28a(u32 a, u32 c)
197{
198 int i = 0;
199 u32 Q1 = 0;
200 u32 R0 = 0;
201
Oliver Endrissebc7de22011-07-03 13:49:44 -0300202 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
203 Q1 = a / c; /* integer part, only the 4 least significant bits
204 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300205
206 /* division using radix 16, 7 nibbles in the result */
207 for (i = 0; i < 7; i++) {
208 Q1 = (Q1 << 4) | (R0 / c);
209 R0 = (R0 % c) << 4;
210 }
211 /* rounding */
212 if ((R0 >> 3) >= c)
213 Q1++;
214
215 return Q1;
216}
217
218static u32 Log10Times100(u32 x)
219{
220 static const u8 scale = 15;
221 static const u8 indexWidth = 5;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300222 u8 i = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300223 u32 y = 0;
224 u32 d = 0;
225 u32 k = 0;
226 u32 r = 0;
227 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300228 log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
229 0 <= n < ((1<<INDEXWIDTH)+1)
230 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300231
232 static const u32 log2lut[] = {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300233 0, /* 0.000000 */
234 290941, /* 290941.300628 */
235 573196, /* 573196.476418 */
236 847269, /* 847269.179851 */
237 1113620, /* 1113620.489452 */
238 1372674, /* 1372673.576986 */
239 1624818, /* 1624817.752104 */
240 1870412, /* 1870411.981536 */
241 2109788, /* 2109787.962654 */
242 2343253, /* 2343252.817465 */
243 2571091, /* 2571091.461923 */
244 2793569, /* 2793568.696416 */
245 3010931, /* 3010931.055901 */
246 3223408, /* 3223408.452106 */
247 3431216, /* 3431215.635215 */
248 3634553, /* 3634553.498355 */
249 3833610, /* 3833610.244726 */
250 4028562, /* 4028562.434393 */
251 4219576, /* 4219575.925308 */
252 4406807, /* 4406806.721144 */
253 4590402, /* 4590401.736809 */
254 4770499, /* 4770499.491025 */
255 4947231, /* 4947230.734179 */
256 5120719, /* 5120719.018555 */
257 5291081, /* 5291081.217197 */
258 5458428, /* 5458427.996830 */
259 5622864, /* 5622864.249668 */
260 5784489, /* 5784489.488298 */
261 5943398, /* 5943398.207380 */
262 6099680, /* 6099680.215452 */
263 6253421, /* 6253420.939751 */
264 6404702, /* 6404701.706649 */
265 6553600, /* 6553600.000000 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300266 };
267
268
269 if (x == 0)
Oliver Endrissebc7de22011-07-03 13:49:44 -0300270 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300271
272 /* Scale x (normalize) */
273 /* computing y in log(x/y) = log(x) - log(y) */
274 if ((x & ((0xffffffff) << (scale + 1))) == 0) {
275 for (k = scale; k > 0; k--) {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300276 if (x & (((u32) 1) << scale))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300277 break;
278 x <<= 1;
279 }
280 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300281 for (k = scale; k < 31; k++) {
282 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300283 break;
284 x >>= 1;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300285 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300286 }
287 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300288 Now x has binary point between bit[scale] and bit[scale-1]
289 and 1.0 <= x < 2.0 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300290
291 /* correction for divison: log(x) = log(x/y)+log(y) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300292 y = k * ((((u32) 1) << scale) * 200);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300293
294 /* remove integer part */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300295 x &= ((((u32) 1) << scale) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300296 /* get index */
297 i = (u8) (x >> (scale - indexWidth));
298 /* compute delta (x - a) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300299 d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300300 /* compute log, multiplication (d* (..)) must be within range ! */
301 y += log2lut[i] +
Oliver Endrissebc7de22011-07-03 13:49:44 -0300302 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300303 /* Conver to log10() */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300304 y /= 108853; /* (log2(10) << scale) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300305 r = (y >> 1);
306 /* rounding */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300307 if (y & ((u32) 1))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300308 r++;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300309 return r;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300310}
311
312/****************************************************************************/
313/* I2C **********************************************************************/
314/****************************************************************************/
315
316static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val)
317{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300318 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
319 .buf = val, .len = 1}
320 };
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300321
322 return i2c_transfer(adapter, msgs, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300323}
324
325static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
326{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300327 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300328 struct i2c_msg msg = {
329 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300330
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300331 dprintk(3, ":");
332 if (debug > 2) {
333 int i;
334 for (i = 0; i < len; i++)
335 printk(KERN_CONT " %02x", data[i]);
336 printk(KERN_CONT "\n");
337 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300338 status = i2c_transfer(adap, &msg, 1);
339 if (status >= 0 && status != 1)
340 status = -EIO;
341
342 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300343 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300344
345 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300346}
347
348static int i2c_read(struct i2c_adapter *adap,
349 u8 adr, u8 *msg, int len, u8 *answ, int alen)
350{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300351 int status;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300352 struct i2c_msg msgs[2] = {
353 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300354 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300355 {.addr = adr, .flags = I2C_M_RD,
356 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300357 };
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300358 dprintk(3, ":");
359 if (debug > 2) {
360 int i;
361 for (i = 0; i < len; i++)
362 printk(KERN_CONT " %02x", msg[i]);
363 printk(KERN_CONT "\n");
364 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300365 status = i2c_transfer(adap, msgs, 2);
366 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300367 if (debug > 2)
368 printk(KERN_CONT ": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300369 if (status >= 0)
370 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300371
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300372 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300373 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300374 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300375 if (debug > 2) {
376 int i;
377 printk(KERN_CONT ": Read ");
378 for (i = 0; i < len; i++)
379 printk(KERN_CONT " %02x", msg[i]);
380 printk(KERN_CONT "\n");
381 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300382 return 0;
383}
384
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300385static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300386{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300387 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300388 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300389
390 if (state->single_master)
391 flags |= 0xC0;
392
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300393 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
394 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
395 mm1[1] = ((reg >> 16) & 0xFF);
396 mm1[2] = ((reg >> 24) & 0xFF) | flags;
397 mm1[3] = ((reg >> 7) & 0xFF);
398 len = 4;
399 } else {
400 mm1[0] = ((reg << 1) & 0xFF);
401 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
402 len = 2;
403 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300404 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300405 status = i2c_read(state->i2c, adr, mm1, len, mm2, 2);
406 if (status < 0)
407 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300408 if (data)
409 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300410
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300411 return 0;
412}
413
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300414static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300415{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300416 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300417}
418
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300419static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300420{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300421 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300422 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300423
424 if (state->single_master)
425 flags |= 0xC0;
426
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300427 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
428 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
429 mm1[1] = ((reg >> 16) & 0xFF);
430 mm1[2] = ((reg >> 24) & 0xFF) | flags;
431 mm1[3] = ((reg >> 7) & 0xFF);
432 len = 4;
433 } else {
434 mm1[0] = ((reg << 1) & 0xFF);
435 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
436 len = 2;
437 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300438 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300439 status = i2c_read(state->i2c, adr, mm1, len, mm2, 4);
440 if (status < 0)
441 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300442 if (data)
443 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300444 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300445
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300446 return 0;
447}
448
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300449static int read32(struct drxk_state *state, u32 reg, u32 *data)
450{
451 return read32_flags(state, reg, data, 0);
452}
453
454static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300455{
456 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300457
458 if (state->single_master)
459 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300460 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
461 mm[0] = (((reg << 1) & 0xFF) | 0x01);
462 mm[1] = ((reg >> 16) & 0xFF);
463 mm[2] = ((reg >> 24) & 0xFF) | flags;
464 mm[3] = ((reg >> 7) & 0xFF);
465 len = 4;
466 } else {
467 mm[0] = ((reg << 1) & 0xFF);
468 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
469 len = 2;
470 }
471 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300472 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300473
474 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300475 return i2c_write(state->i2c, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300476}
477
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300478static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300479{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300480 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300481}
482
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300483static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300484{
485 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300486
487 if (state->single_master)
488 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300489 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
490 mm[0] = (((reg << 1) & 0xFF) | 0x01);
491 mm[1] = ((reg >> 16) & 0xFF);
492 mm[2] = ((reg >> 24) & 0xFF) | flags;
493 mm[3] = ((reg >> 7) & 0xFF);
494 len = 4;
495 } else {
496 mm[0] = ((reg << 1) & 0xFF);
497 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
498 len = 2;
499 }
500 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300501 mm[len + 1] = (data >> 8) & 0xff;
502 mm[len + 2] = (data >> 16) & 0xff;
503 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300504 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300505
506 return i2c_write(state->i2c, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300507}
508
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300509static int write32(struct drxk_state *state, u32 reg, u32 data)
510{
511 return write32_flags(state, reg, data, 0);
512}
513
514static int write_block(struct drxk_state *state, u32 Address,
515 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300516{
517 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300518 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300519
520 if (state->single_master)
521 Flags |= 0xC0;
522
Oliver Endrissebc7de22011-07-03 13:49:44 -0300523 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300524 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300525 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300526 u8 *AdrBuf = &state->Chunk[0];
527 u32 AdrLength = 0;
528
Oliver Endrissebc7de22011-07-03 13:49:44 -0300529 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
530 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
531 AdrBuf[1] = ((Address >> 16) & 0xFF);
532 AdrBuf[2] = ((Address >> 24) & 0xFF);
533 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300534 AdrBuf[2] |= Flags;
535 AdrLength = 4;
536 if (Chunk == state->m_ChunkSize)
537 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300538 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300539 AdrBuf[0] = ((Address << 1) & 0xFF);
540 AdrBuf[1] = (((Address >> 16) & 0x0F) |
541 ((Address >> 18) & 0xF0));
542 AdrLength = 2;
543 }
544 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300545 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
546 if (debug > 1) {
547 int i;
548 if (pBlock)
549 for (i = 0; i < Chunk; i++)
550 printk(KERN_CONT " %02x", pBlock[i]);
551 printk(KERN_CONT "\n");
552 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300553 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300554 &state->Chunk[0], Chunk + AdrLength);
555 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300556 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
557 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300558 break;
559 }
560 pBlock += Chunk;
561 Address += (Chunk >> 1);
562 BlkSize -= Chunk;
563 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300564 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300565}
566
567#ifndef DRXK_MAX_RETRIES_POWERUP
568#define DRXK_MAX_RETRIES_POWERUP 20
569#endif
570
571int PowerUpDevice(struct drxk_state *state)
572{
573 int status;
574 u8 data = 0;
575 u16 retryCount = 0;
576
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300577 dprintk(1, "\n");
578
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300579 status = i2c_read1(state->i2c, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300580 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300581 do {
582 data = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300583 status = i2c_write(state->i2c, state->demod_address,
584 &data, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300585 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300586 retryCount++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300587 if (status < 0)
588 continue;
589 status = i2c_read1(state->i2c, state->demod_address,
590 &data);
591 } while (status < 0 &&
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300592 (retryCount < DRXK_MAX_RETRIES_POWERUP));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300593 if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
594 goto error;
595 }
596
597 /* Make sure all clk domains are active */
598 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
599 if (status < 0)
600 goto error;
601 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
602 if (status < 0)
603 goto error;
604 /* Enable pll lock tests */
605 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
606 if (status < 0)
607 goto error;
608
609 state->m_currentPowerMode = DRX_POWER_UP;
610
611error:
612 if (status < 0)
613 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
614
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300615 return status;
616}
617
618
619static int init_state(struct drxk_state *state)
620{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -0300621 /*
622 * FIXME: most (all?) of the values bellow should be moved into
623 * struct drxk_config, as they are probably board-specific
624 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300625 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
626 u32 ulVSBIfAgcOutputLevel = 0;
627 u32 ulVSBIfAgcMinLevel = 0;
628 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
629 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300630
Oliver Endrissebc7de22011-07-03 13:49:44 -0300631 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
632 u32 ulVSBRfAgcOutputLevel = 0;
633 u32 ulVSBRfAgcMinLevel = 0;
634 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
635 u32 ulVSBRfAgcSpeed = 3;
636 u32 ulVSBRfAgcTop = 9500;
637 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300638
Oliver Endrissebc7de22011-07-03 13:49:44 -0300639 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
640 u32 ulATVIfAgcOutputLevel = 0;
641 u32 ulATVIfAgcMinLevel = 0;
642 u32 ulATVIfAgcMaxLevel = 0;
643 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300644
Oliver Endrissebc7de22011-07-03 13:49:44 -0300645 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
646 u32 ulATVRfAgcOutputLevel = 0;
647 u32 ulATVRfAgcMinLevel = 0;
648 u32 ulATVRfAgcMaxLevel = 0;
649 u32 ulATVRfAgcTop = 9500;
650 u32 ulATVRfAgcCutOffCurrent = 4000;
651 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300652
653 u32 ulQual83 = DEFAULT_MER_83;
654 u32 ulQual93 = DEFAULT_MER_93;
655
656 u32 ulDVBTStaticTSClock = 1;
657 u32 ulDVBCStaticTSClock = 1;
658
659 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
660 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
661
662 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
663 /* io_pad_cfg_mode output mode is drive always */
664 /* io_pad_cfg_drive is set to power 2 (23 mA) */
665 u32 ulGPIOCfg = 0x0113;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300666 u32 ulGPIO = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300667 u32 ulSerialMode = 1;
668 u32 ulInvertTSClock = 0;
669 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
670 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
671 u32 ulDVBTBitrate = 50000000;
672 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
673
674 u32 ulInsertRSByte = 0;
675
676 u32 ulRfMirror = 1;
677 u32 ulPowerDown = 0;
678
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300679 dprintk(1, "\n");
680
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300681 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300682 state->m_hasDVBT = false;
683 state->m_hasDVBC = false;
684 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300685 state->m_hasOOB = false;
686 state->m_hasAudio = false;
687
688 state->m_ChunkSize = 124;
689
690 state->m_oscClockFreq = 0;
691 state->m_smartAntInverted = false;
692 state->m_bPDownOpenBridge = false;
693
694 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300695 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300696 /* Timing div, 250ns/Psys */
697 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
698 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
699 HI_I2C_DELAY) / 1000;
700 /* Clipping */
701 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
702 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
703 state->m_HICfgWakeUpKey = (state->demod_address << 1);
704 /* port/bridge/power down ctrl */
705 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
706
707 state->m_bPowerDown = (ulPowerDown != 0);
708
709 state->m_DRXK_A1_PATCH_CODE = false;
710 state->m_DRXK_A1_ROM_CODE = false;
711 state->m_DRXK_A2_ROM_CODE = false;
712 state->m_DRXK_A3_ROM_CODE = false;
713 state->m_DRXK_A2_PATCH_CODE = false;
714 state->m_DRXK_A3_PATCH_CODE = false;
715
716 /* Init AGC and PGA parameters */
717 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300718 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
719 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
720 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
721 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
722 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300723 state->m_vsbPgaCfg = 140;
724
725 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300726 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
727 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
728 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
729 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
730 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
731 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
732 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
733 state->m_vsbPreSawCfg.reference = 0x07;
734 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300735
736 state->m_Quality83percent = DEFAULT_MER_83;
737 state->m_Quality93percent = DEFAULT_MER_93;
738 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
739 state->m_Quality83percent = ulQual83;
740 state->m_Quality93percent = ulQual93;
741 }
742
743 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300744 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
745 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
746 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
747 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
748 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300749
750 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300751 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
752 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
753 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
754 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
755 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
756 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
757 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
758 state->m_atvPreSawCfg.reference = 0x04;
759 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300760
761
762 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300763 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
764 state->m_dvbtRfAgcCfg.outputLevel = 0;
765 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
766 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
767 state->m_dvbtRfAgcCfg.top = 0x2100;
768 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
769 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300770
771
772 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300773 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
774 state->m_dvbtIfAgcCfg.outputLevel = 0;
775 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
776 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
777 state->m_dvbtIfAgcCfg.top = 13424;
778 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
779 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300780 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300781 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
782 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300783
Oliver Endrissebc7de22011-07-03 13:49:44 -0300784 state->m_dvbtPreSawCfg.reference = 4;
785 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300786
787 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300788 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
789 state->m_qamRfAgcCfg.outputLevel = 0;
790 state->m_qamRfAgcCfg.minOutputLevel = 6023;
791 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
792 state->m_qamRfAgcCfg.top = 0x2380;
793 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
794 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300795
796 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300797 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
798 state->m_qamIfAgcCfg.outputLevel = 0;
799 state->m_qamIfAgcCfg.minOutputLevel = 0;
800 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
801 state->m_qamIfAgcCfg.top = 0x0511;
802 state->m_qamIfAgcCfg.cutOffCurrent = 0;
803 state->m_qamIfAgcCfg.speed = 3;
804 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300805 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
806
Oliver Endrissebc7de22011-07-03 13:49:44 -0300807 state->m_qamPgaCfg = 140;
808 state->m_qamPreSawCfg.reference = 4;
809 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300810
811 state->m_OperationMode = OM_NONE;
812 state->m_DrxkState = DRXK_UNINITIALIZED;
813
814 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300815 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
816 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
817 state->m_enableParallel = true; /* If TRUE;
818 parallel out otherwise serial */
819 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
820 state->m_invertERR = false; /* If TRUE; invert ERR signal */
821 state->m_invertSTR = false; /* If TRUE; invert STR signals */
822 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
823 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300824 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300825 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300826 /* If TRUE; static MPEG clockrate will be used;
827 otherwise clockrate will adapt to the bitrate of the TS */
828
829 state->m_DVBTBitrate = ulDVBTBitrate;
830 state->m_DVBCBitrate = ulDVBCBitrate;
831
832 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
833 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
834
835 /* Maximum bitrate in b/s in case static clockrate is selected */
836 state->m_mpegTsStaticBitrate = 19392658;
837 state->m_disableTEIhandling = false;
838
839 if (ulInsertRSByte)
840 state->m_insertRSByte = true;
841
842 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
843 if (ulMpegLockTimeOut < 10000)
844 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
845 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
846 if (ulDemodLockTimeOut < 10000)
847 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
848
Oliver Endrissebc7de22011-07-03 13:49:44 -0300849 /* QAM defaults */
850 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300851 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300852 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
853 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300854
855 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
856 state->m_agcFastClipCtrlDelay = 0;
857
858 state->m_GPIOCfg = (ulGPIOCfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300859
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300860 state->m_bPowerDown = false;
861 state->m_currentPowerMode = DRX_POWER_DOWN;
862
863 state->m_enableParallel = (ulSerialMode == 0);
864
865 state->m_rfmirror = (ulRfMirror == 0);
866 state->m_IfAgcPol = false;
867 return 0;
868}
869
870static int DRXX_Open(struct drxk_state *state)
871{
872 int status = 0;
873 u32 jtag = 0;
874 u16 bid = 0;
875 u16 key = 0;
876
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300877 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300878 /* stop lock indicator process */
879 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
880 if (status < 0)
881 goto error;
882 /* Check device id */
883 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
884 if (status < 0)
885 goto error;
886 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
887 if (status < 0)
888 goto error;
889 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
890 if (status < 0)
891 goto error;
892 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
893 if (status < 0)
894 goto error;
895 status = write16(state, SIO_TOP_COMM_KEY__A, key);
896error:
897 if (status < 0)
898 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300899 return status;
900}
901
902static int GetDeviceCapabilities(struct drxk_state *state)
903{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300904 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300905 u32 sioTopJtagidLo = 0;
906 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300907 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300908
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300909 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300910
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300911 /* driver 0.9.0 */
912 /* stop lock indicator process */
913 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
914 if (status < 0)
915 goto error;
916 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
917 if (status < 0)
918 goto error;
919 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
920 if (status < 0)
921 goto error;
922 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
923 if (status < 0)
924 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300925
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300926 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
927 case 0:
928 /* ignore (bypass ?) */
929 break;
930 case 1:
931 /* 27 MHz */
932 state->m_oscClockFreq = 27000;
933 break;
934 case 2:
935 /* 20.25 MHz */
936 state->m_oscClockFreq = 20250;
937 break;
938 case 3:
939 /* 4 MHz */
940 state->m_oscClockFreq = 20250;
941 break;
942 default:
943 printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
944 return -EINVAL;
945 }
946 /*
947 Determine device capabilities
948 Based on pinning v14
949 */
950 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
951 if (status < 0)
952 goto error;
953 /* driver 0.9.0 */
954 switch ((sioTopJtagidLo >> 29) & 0xF) {
955 case 0:
956 state->m_deviceSpin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300957 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300958 break;
959 case 2:
960 state->m_deviceSpin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300961 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300962 break;
963 case 3:
964 state->m_deviceSpin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300965 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300966 break;
967 default:
968 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
969 status = -EINVAL;
970 printk(KERN_ERR "drxk: Spin unknown\n");
971 goto error2;
972 }
973 switch ((sioTopJtagidLo >> 12) & 0xFF) {
974 case 0x13:
975 /* typeId = DRX3913K_TYPE_ID */
976 state->m_hasLNA = false;
977 state->m_hasOOB = false;
978 state->m_hasATV = false;
979 state->m_hasAudio = false;
980 state->m_hasDVBT = true;
981 state->m_hasDVBC = true;
982 state->m_hasSAWSW = true;
983 state->m_hasGPIO2 = false;
984 state->m_hasGPIO1 = false;
985 state->m_hasIRQN = false;
986 break;
987 case 0x15:
988 /* typeId = DRX3915K_TYPE_ID */
989 state->m_hasLNA = false;
990 state->m_hasOOB = false;
991 state->m_hasATV = true;
992 state->m_hasAudio = false;
993 state->m_hasDVBT = true;
994 state->m_hasDVBC = false;
995 state->m_hasSAWSW = true;
996 state->m_hasGPIO2 = true;
997 state->m_hasGPIO1 = true;
998 state->m_hasIRQN = false;
999 break;
1000 case 0x16:
1001 /* typeId = DRX3916K_TYPE_ID */
1002 state->m_hasLNA = false;
1003 state->m_hasOOB = false;
1004 state->m_hasATV = true;
1005 state->m_hasAudio = false;
1006 state->m_hasDVBT = true;
1007 state->m_hasDVBC = false;
1008 state->m_hasSAWSW = true;
1009 state->m_hasGPIO2 = true;
1010 state->m_hasGPIO1 = true;
1011 state->m_hasIRQN = false;
1012 break;
1013 case 0x18:
1014 /* typeId = DRX3918K_TYPE_ID */
1015 state->m_hasLNA = false;
1016 state->m_hasOOB = false;
1017 state->m_hasATV = true;
1018 state->m_hasAudio = true;
1019 state->m_hasDVBT = true;
1020 state->m_hasDVBC = false;
1021 state->m_hasSAWSW = true;
1022 state->m_hasGPIO2 = true;
1023 state->m_hasGPIO1 = true;
1024 state->m_hasIRQN = false;
1025 break;
1026 case 0x21:
1027 /* typeId = DRX3921K_TYPE_ID */
1028 state->m_hasLNA = false;
1029 state->m_hasOOB = false;
1030 state->m_hasATV = true;
1031 state->m_hasAudio = true;
1032 state->m_hasDVBT = true;
1033 state->m_hasDVBC = true;
1034 state->m_hasSAWSW = true;
1035 state->m_hasGPIO2 = true;
1036 state->m_hasGPIO1 = true;
1037 state->m_hasIRQN = false;
1038 break;
1039 case 0x23:
1040 /* typeId = DRX3923K_TYPE_ID */
1041 state->m_hasLNA = false;
1042 state->m_hasOOB = false;
1043 state->m_hasATV = true;
1044 state->m_hasAudio = true;
1045 state->m_hasDVBT = true;
1046 state->m_hasDVBC = true;
1047 state->m_hasSAWSW = true;
1048 state->m_hasGPIO2 = true;
1049 state->m_hasGPIO1 = true;
1050 state->m_hasIRQN = false;
1051 break;
1052 case 0x25:
1053 /* typeId = DRX3925K_TYPE_ID */
1054 state->m_hasLNA = false;
1055 state->m_hasOOB = false;
1056 state->m_hasATV = true;
1057 state->m_hasAudio = true;
1058 state->m_hasDVBT = true;
1059 state->m_hasDVBC = true;
1060 state->m_hasSAWSW = true;
1061 state->m_hasGPIO2 = true;
1062 state->m_hasGPIO1 = true;
1063 state->m_hasIRQN = false;
1064 break;
1065 case 0x26:
1066 /* typeId = DRX3926K_TYPE_ID */
1067 state->m_hasLNA = false;
1068 state->m_hasOOB = false;
1069 state->m_hasATV = true;
1070 state->m_hasAudio = false;
1071 state->m_hasDVBT = true;
1072 state->m_hasDVBC = true;
1073 state->m_hasSAWSW = true;
1074 state->m_hasGPIO2 = true;
1075 state->m_hasGPIO1 = true;
1076 state->m_hasIRQN = false;
1077 break;
1078 default:
1079 printk(KERN_ERR "drxk: DeviceID not supported = %02x\n",
1080 ((sioTopJtagidLo >> 12) & 0xFF));
1081 status = -EINVAL;
1082 goto error2;
1083 }
1084
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -03001085 printk(KERN_INFO
1086 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
1087 ((sioTopJtagidLo >> 12) & 0xFF), spin,
1088 state->m_oscClockFreq / 1000,
1089 state->m_oscClockFreq % 1000);
1090
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001091error:
1092 if (status < 0)
1093 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1094
1095error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001096 return status;
1097}
1098
1099static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1100{
1101 int status;
1102 bool powerdown_cmd;
1103
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001104 dprintk(1, "\n");
1105
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001106 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001107 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001108 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001109 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001110 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1111 msleep(1);
1112
1113 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001114 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1115 ((state->m_HICfgCtrl) &
1116 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1117 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001118 if (powerdown_cmd == false) {
1119 /* Wait until command rdy */
1120 u32 retryCount = 0;
1121 u16 waitCmd;
1122
1123 do {
1124 msleep(1);
1125 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001126 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1127 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001128 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1129 && (waitCmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001130 if (status < 0)
1131 goto error;
1132 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001133 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001134error:
1135 if (status < 0)
1136 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1137
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001138 return status;
1139}
1140
1141static int HI_CfgCommand(struct drxk_state *state)
1142{
1143 int status;
1144
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001145 dprintk(1, "\n");
1146
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001147 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001148
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001149 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1150 if (status < 0)
1151 goto error;
1152 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1153 if (status < 0)
1154 goto error;
1155 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1156 if (status < 0)
1157 goto error;
1158 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1159 if (status < 0)
1160 goto error;
1161 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1162 if (status < 0)
1163 goto error;
1164 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1165 if (status < 0)
1166 goto error;
1167 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1168 if (status < 0)
1169 goto error;
1170
1171 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1172error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001173 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001174 if (status < 0)
1175 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001176 return status;
1177}
1178
1179static int InitHI(struct drxk_state *state)
1180{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001181 dprintk(1, "\n");
1182
Oliver Endrissebc7de22011-07-03 13:49:44 -03001183 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001184 state->m_HICfgTimeout = 0x96FF;
1185 /* port/bridge/power down ctrl */
1186 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001187
Oliver Endrissebc7de22011-07-03 13:49:44 -03001188 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001189}
1190
1191static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1192{
1193 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001194 u16 sioPdrMclkCfg = 0;
1195 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001196
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001197 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001198
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001199 /* stop lock indicator process */
1200 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1201 if (status < 0)
1202 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001203
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001204 /* MPEG TS pad configuration */
1205 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1206 if (status < 0)
1207 goto error;
1208
1209 if (mpegEnable == false) {
1210 /* Set MPEG TS pads to inputmode */
1211 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1212 if (status < 0)
1213 goto error;
1214 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1215 if (status < 0)
1216 goto error;
1217 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1218 if (status < 0)
1219 goto error;
1220 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1221 if (status < 0)
1222 goto error;
1223 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1224 if (status < 0)
1225 goto error;
1226 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1227 if (status < 0)
1228 goto error;
1229 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1230 if (status < 0)
1231 goto error;
1232 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1233 if (status < 0)
1234 goto error;
1235 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1236 if (status < 0)
1237 goto error;
1238 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1239 if (status < 0)
1240 goto error;
1241 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1242 if (status < 0)
1243 goto error;
1244 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1245 if (status < 0)
1246 goto error;
1247 } else {
1248 /* Enable MPEG output */
1249 sioPdrMdxCfg =
1250 ((state->m_TSDataStrength <<
1251 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1252 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1253 SIO_PDR_MCLK_CFG_DRIVE__B) |
1254 0x0003);
1255
1256 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1257 if (status < 0)
1258 goto error;
1259 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
1260 if (status < 0)
1261 goto error;
1262 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
1263 if (status < 0)
1264 goto error;
1265 if (state->m_enableParallel == true) {
1266 /* paralel -> enable MD1 to MD7 */
1267 status = write16(state, SIO_PDR_MD1_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_MD2_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_MD3_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_MD4_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_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001280 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001281 goto error;
1282 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1283 if (status < 0)
1284 goto error;
1285 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1286 if (status < 0)
1287 goto error;
1288 } else {
1289 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1290 SIO_PDR_MD0_CFG_DRIVE__B)
1291 | 0x0003);
1292 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001293 status = write16(state, SIO_PDR_MD1_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_MD2_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_MD3_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_MD4_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_MD5_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_MD6_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;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001311 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001312 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001313 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001314 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001315 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001316 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001317 goto error;
1318 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001319 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001320 goto error;
1321 }
1322 /* Enable MB output over MPEG pads and ctl input */
1323 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1324 if (status < 0)
1325 goto error;
1326 /* Write nomagic word to enable pdr reg write */
1327 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1328error:
1329 if (status < 0)
1330 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001331 return status;
1332}
1333
1334static int MPEGTSDisable(struct drxk_state *state)
1335{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001336 dprintk(1, "\n");
1337
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001338 return MPEGTSConfigurePins(state, false);
1339}
1340
1341static int BLChainCmd(struct drxk_state *state,
1342 u16 romOffset, u16 nrOfElements, u32 timeOut)
1343{
1344 u16 blStatus = 0;
1345 int status;
1346 unsigned long end;
1347
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001348 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001349 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001350 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1351 if (status < 0)
1352 goto error;
1353 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1354 if (status < 0)
1355 goto error;
1356 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1357 if (status < 0)
1358 goto error;
1359 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1360 if (status < 0)
1361 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001362
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001363 end = jiffies + msecs_to_jiffies(timeOut);
1364 do {
1365 msleep(1);
1366 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1367 if (status < 0)
1368 goto error;
1369 } while ((blStatus == 0x1) &&
1370 ((time_is_after_jiffies(end))));
1371
1372 if (blStatus == 0x1) {
1373 printk(KERN_ERR "drxk: SIO not ready\n");
1374 status = -EINVAL;
1375 goto error2;
1376 }
1377error:
1378 if (status < 0)
1379 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1380error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001381 mutex_unlock(&state->mutex);
1382 return status;
1383}
1384
1385
1386static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001387 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001388{
1389 const u8 *pSrc = pMCImage;
1390 u16 Flags;
1391 u16 Drain;
1392 u32 Address;
1393 u16 nBlocks;
1394 u16 BlockSize;
1395 u16 BlockCRC;
1396 u32 offset = 0;
1397 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001398 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001399
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001400 dprintk(1, "\n");
1401
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001402 /* down the drain (we don care about MAGIC_WORD) */
1403 Drain = (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 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001407 pSrc += sizeof(u16);
1408 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001409
1410 for (i = 0; i < nBlocks; i += 1) {
1411 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001412 (pSrc[2] << 8) | pSrc[3];
1413 pSrc += sizeof(u32);
1414 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001415
1416 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001417 pSrc += sizeof(u16);
1418 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001419
1420 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001421 pSrc += sizeof(u16);
1422 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001423
1424 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001425 pSrc += sizeof(u16);
1426 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001427
1428 if (offset + BlockSize > Length) {
1429 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1430 return -EINVAL;
1431 }
1432
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001433 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001434 if (status < 0) {
1435 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001436 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001437 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001438 pSrc += BlockSize;
1439 offset += BlockSize;
1440 }
1441 return status;
1442}
1443
1444static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1445{
1446 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001447 u16 data = 0;
1448 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001449 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1450 unsigned long end;
1451
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001452 dprintk(1, "\n");
1453
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001454 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001455 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001456 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1457 }
1458
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001459 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1460 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001461 /* tokenring already has correct status */
1462 return status;
1463 }
1464 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001465 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001466
Oliver Endrissebc7de22011-07-03 13:49:44 -03001467 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001468 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001469 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001470 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001471 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001472 msleep(1);
1473 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001474 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001475 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001476 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001477 }
1478 return status;
1479}
1480
1481static int MPEGTSStop(struct drxk_state *state)
1482{
1483 int status = 0;
1484 u16 fecOcSncMode = 0;
1485 u16 fecOcIprMode = 0;
1486
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001487 dprintk(1, "\n");
1488
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001489 /* Gracefull shutdown (byte boundaries) */
1490 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1491 if (status < 0)
1492 goto error;
1493 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1494 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1495 if (status < 0)
1496 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001497
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001498 /* Suppress MCLK during absence of data */
1499 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1500 if (status < 0)
1501 goto error;
1502 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1503 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1504
1505error:
1506 if (status < 0)
1507 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1508
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001509 return status;
1510}
1511
1512static int scu_command(struct drxk_state *state,
1513 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001514 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001515{
1516#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1517#error DRXK register mapping no longer compatible with this routine!
1518#endif
1519 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001520 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001521 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001522 u8 buffer[34];
1523 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001524 const char *p;
1525 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001526
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001527 dprintk(1, "\n");
1528
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001529 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1530 ((resultLen > 0) && (result == NULL)))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001531 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001532
1533 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001534
1535 /* assume that the command register is ready
1536 since it is checked afterwards */
1537 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1538 buffer[cnt++] = (parameter[ii] & 0xFF);
1539 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1540 }
1541 buffer[cnt++] = (cmd & 0xFF);
1542 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1543
1544 write_block(state, SCU_RAM_PARAM_0__A -
1545 (parameterLen - 1), cnt, buffer);
1546 /* Wait until SCU has processed command */
1547 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001548 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001549 msleep(1);
1550 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1551 if (status < 0)
1552 goto error;
1553 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1554 if (curCmd != DRX_SCU_READY) {
1555 printk(KERN_ERR "drxk: SCU not ready\n");
1556 status = -EIO;
1557 goto error2;
1558 }
1559 /* read results */
1560 if ((resultLen > 0) && (result != NULL)) {
1561 s16 err;
1562 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001563
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001564 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1565 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001566 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001567 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001568 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001569
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001570 /* Check if an error was reported by SCU */
1571 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001572 if (err >= 0)
1573 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001574
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001575 /* check for the known error codes */
1576 switch (err) {
1577 case SCU_RESULT_UNKCMD:
1578 p = "SCU_RESULT_UNKCMD";
1579 break;
1580 case SCU_RESULT_UNKSTD:
1581 p = "SCU_RESULT_UNKSTD";
1582 break;
1583 case SCU_RESULT_SIZE:
1584 p = "SCU_RESULT_SIZE";
1585 break;
1586 case SCU_RESULT_INVPAR:
1587 p = "SCU_RESULT_INVPAR";
1588 break;
1589 default: /* Other negative values are errors */
1590 sprintf(errname, "ERROR: %d\n", err);
1591 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001592 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001593 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1594 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1595 status = -EINVAL;
1596 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001597 }
1598
1599error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001600 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001601 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001602error2:
1603 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001604 return status;
1605}
1606
1607static int SetIqmAf(struct drxk_state *state, bool active)
1608{
1609 u16 data = 0;
1610 int status;
1611
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001612 dprintk(1, "\n");
1613
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001614 /* Configure IQM */
1615 status = read16(state, IQM_AF_STDBY__A, &data);
1616 if (status < 0)
1617 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001618
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001619 if (!active) {
1620 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1621 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1622 | IQM_AF_STDBY_STDBY_PD_STANDBY
1623 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1624 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1625 } else {
1626 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1627 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1628 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1629 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1630 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1631 );
1632 }
1633 status = write16(state, IQM_AF_STDBY__A, data);
1634
1635error:
1636 if (status < 0)
1637 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001638 return status;
1639}
1640
Oliver Endrissebc7de22011-07-03 13:49:44 -03001641static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001642{
1643 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001644 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001645
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001646 dprintk(1, "\n");
1647
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001648 /* Check arguments */
1649 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001650 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001651
1652 switch (*mode) {
1653 case DRX_POWER_UP:
1654 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1655 break;
1656 case DRXK_POWER_DOWN_OFDM:
1657 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1658 break;
1659 case DRXK_POWER_DOWN_CORE:
1660 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1661 break;
1662 case DRXK_POWER_DOWN_PLL:
1663 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1664 break;
1665 case DRX_POWER_DOWN:
1666 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1667 break;
1668 default:
1669 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001670 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001671 break;
1672 }
1673
1674 /* If already in requested power mode, do nothing */
1675 if (state->m_currentPowerMode == *mode)
1676 return 0;
1677
1678 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001679 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001680 status = PowerUpDevice(state);
1681 if (status < 0)
1682 goto error;
1683 status = DVBTEnableOFDMTokenRing(state, true);
1684 if (status < 0)
1685 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001686 }
1687
1688 if (*mode == DRX_POWER_UP) {
1689 /* Restore analog & pin configuartion */
1690 } else {
1691 /* Power down to requested mode */
1692 /* Backup some register settings */
1693 /* Set pins with possible pull-ups connected
1694 to them in input mode */
1695 /* Analog power down */
1696 /* ADC power down */
1697 /* Power down device */
1698 /* stop all comm_exec */
1699 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001700 switch (state->m_OperationMode) {
1701 case OM_DVBT:
1702 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001703 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001704 goto error;
1705 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001706 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001707 goto error;
1708 break;
1709 case OM_QAM_ITU_A:
1710 case OM_QAM_ITU_C:
1711 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001712 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001713 goto error;
1714 status = PowerDownQAM(state);
1715 if (status < 0)
1716 goto error;
1717 break;
1718 default:
1719 break;
1720 }
1721 status = DVBTEnableOFDMTokenRing(state, false);
1722 if (status < 0)
1723 goto error;
1724 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1725 if (status < 0)
1726 goto error;
1727 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1728 if (status < 0)
1729 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001730
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001731 if (*mode != DRXK_POWER_DOWN_OFDM) {
1732 state->m_HICfgCtrl |=
1733 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1734 status = HI_CfgCommand(state);
1735 if (status < 0)
1736 goto error;
1737 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001738 }
1739 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001740
1741error:
1742 if (status < 0)
1743 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1744
Oliver Endrissebc7de22011-07-03 13:49:44 -03001745 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001746}
1747
1748static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1749{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001750 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001751 u16 cmdResult = 0;
1752 u16 data = 0;
1753 int status;
1754
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001755 dprintk(1, "\n");
1756
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001757 status = read16(state, SCU_COMM_EXEC__A, &data);
1758 if (status < 0)
1759 goto error;
1760 if (data == SCU_COMM_EXEC_ACTIVE) {
1761 /* Send OFDM stop command */
1762 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 -03001763 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001764 goto error;
1765 /* Send OFDM reset command */
1766 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1767 if (status < 0)
1768 goto error;
1769 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001770
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001771 /* Reset datapath for OFDM, processors first */
1772 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1773 if (status < 0)
1774 goto error;
1775 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1776 if (status < 0)
1777 goto error;
1778 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1779 if (status < 0)
1780 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001781
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001782 /* powerdown AFE */
1783 status = SetIqmAf(state, false);
1784 if (status < 0)
1785 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001786
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001787 /* powerdown to OFDM mode */
1788 if (setPowerMode) {
1789 status = CtrlPowerMode(state, &powerMode);
1790 if (status < 0)
1791 goto error;
1792 }
1793error:
1794 if (status < 0)
1795 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001796 return status;
1797}
1798
Oliver Endrissebc7de22011-07-03 13:49:44 -03001799static int SetOperationMode(struct drxk_state *state,
1800 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001801{
1802 int status = 0;
1803
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001804 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001805 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001806 Stop and power down previous standard
1807 TODO investigate total power down instead of partial
1808 power down depending on "previous" standard.
1809 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001810
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001811 /* disable HW lock indicator */
1812 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1813 if (status < 0)
1814 goto error;
1815
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001816 /* Device is already at the required mode */
1817 if (state->m_OperationMode == oMode)
1818 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001819
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001820 switch (state->m_OperationMode) {
1821 /* OM_NONE was added for start up */
1822 case OM_NONE:
1823 break;
1824 case OM_DVBT:
1825 status = MPEGTSStop(state);
1826 if (status < 0)
1827 goto error;
1828 status = PowerDownDVBT(state, true);
1829 if (status < 0)
1830 goto error;
1831 state->m_OperationMode = OM_NONE;
1832 break;
1833 case OM_QAM_ITU_A: /* fallthrough */
1834 case OM_QAM_ITU_C:
1835 status = MPEGTSStop(state);
1836 if (status < 0)
1837 goto error;
1838 status = PowerDownQAM(state);
1839 if (status < 0)
1840 goto error;
1841 state->m_OperationMode = OM_NONE;
1842 break;
1843 case OM_QAM_ITU_B:
1844 default:
1845 status = -EINVAL;
1846 goto error;
1847 }
1848
1849 /*
1850 Power up new standard
1851 */
1852 switch (oMode) {
1853 case OM_DVBT:
1854 state->m_OperationMode = oMode;
1855 status = SetDVBTStandard(state, oMode);
1856 if (status < 0)
1857 goto error;
1858 break;
1859 case OM_QAM_ITU_A: /* fallthrough */
1860 case OM_QAM_ITU_C:
1861 state->m_OperationMode = oMode;
1862 status = SetQAMStandard(state, oMode);
1863 if (status < 0)
1864 goto error;
1865 break;
1866 case OM_QAM_ITU_B:
1867 default:
1868 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001869 }
1870error:
1871 if (status < 0)
1872 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1873 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001874}
1875
1876static int Start(struct drxk_state *state, s32 offsetFreq,
1877 s32 IntermediateFrequency)
1878{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001879 int status = -EINVAL;
1880
1881 u16 IFreqkHz;
1882 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001883
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001884 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001885 if (state->m_DrxkState != DRXK_STOPPED &&
1886 state->m_DrxkState != DRXK_DTV_STARTED)
1887 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001888
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001889 state->m_bMirrorFreqSpect = (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001890
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001891 if (IntermediateFrequency < 0) {
1892 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1893 IntermediateFrequency = -IntermediateFrequency;
1894 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001895
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001896 switch (state->m_OperationMode) {
1897 case OM_QAM_ITU_A:
1898 case OM_QAM_ITU_C:
1899 IFreqkHz = (IntermediateFrequency / 1000);
1900 status = SetQAM(state, IFreqkHz, OffsetkHz);
1901 if (status < 0)
1902 goto error;
1903 state->m_DrxkState = DRXK_DTV_STARTED;
1904 break;
1905 case OM_DVBT:
1906 IFreqkHz = (IntermediateFrequency / 1000);
1907 status = MPEGTSStop(state);
1908 if (status < 0)
1909 goto error;
1910 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1911 if (status < 0)
1912 goto error;
1913 status = DVBTStart(state);
1914 if (status < 0)
1915 goto error;
1916 state->m_DrxkState = DRXK_DTV_STARTED;
1917 break;
1918 default:
1919 break;
1920 }
1921error:
1922 if (status < 0)
1923 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001924 return status;
1925}
1926
1927static int ShutDown(struct drxk_state *state)
1928{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001929 dprintk(1, "\n");
1930
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001931 MPEGTSStop(state);
1932 return 0;
1933}
1934
Oliver Endrissebc7de22011-07-03 13:49:44 -03001935static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1936 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001937{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001938 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001939
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001940 dprintk(1, "\n");
1941
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001942 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001943 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001944
1945 *pLockStatus = NOT_LOCKED;
1946
1947 /* define the SCU command code */
1948 switch (state->m_OperationMode) {
1949 case OM_QAM_ITU_A:
1950 case OM_QAM_ITU_B:
1951 case OM_QAM_ITU_C:
1952 status = GetQAMLockStatus(state, pLockStatus);
1953 break;
1954 case OM_DVBT:
1955 status = GetDVBTLockStatus(state, pLockStatus);
1956 break;
1957 default:
1958 break;
1959 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001960error:
1961 if (status < 0)
1962 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001963 return status;
1964}
1965
1966static int MPEGTSStart(struct drxk_state *state)
1967{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001968 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001969
1970 u16 fecOcSncMode = 0;
1971
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001972 /* Allow OC to sync again */
1973 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1974 if (status < 0)
1975 goto error;
1976 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1977 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1978 if (status < 0)
1979 goto error;
1980 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1981error:
1982 if (status < 0)
1983 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001984 return status;
1985}
1986
1987static int MPEGTSDtoInit(struct drxk_state *state)
1988{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001989 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001990
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001991 dprintk(1, "\n");
1992
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001993 /* Rate integration settings */
1994 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1995 if (status < 0)
1996 goto error;
1997 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1998 if (status < 0)
1999 goto error;
2000 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
2001 if (status < 0)
2002 goto error;
2003 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
2004 if (status < 0)
2005 goto error;
2006 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2007 if (status < 0)
2008 goto error;
2009 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2010 if (status < 0)
2011 goto error;
2012 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2013 if (status < 0)
2014 goto error;
2015 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2016 if (status < 0)
2017 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002018
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002019 /* Additional configuration */
2020 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2021 if (status < 0)
2022 goto error;
2023 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2024 if (status < 0)
2025 goto error;
2026 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2027error:
2028 if (status < 0)
2029 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2030
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002031 return status;
2032}
2033
Oliver Endrissebc7de22011-07-03 13:49:44 -03002034static int MPEGTSDtoSetup(struct drxk_state *state,
2035 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002036{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002037 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002038
Oliver Endrissebc7de22011-07-03 13:49:44 -03002039 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2040 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2041 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2042 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2043 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2044 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2045 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002046 u16 fecOcTmdMode = 0;
2047 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002048 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002049 bool staticCLK = false;
2050
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002051 dprintk(1, "\n");
2052
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002053 /* Check insertion of the Reed-Solomon parity bytes */
2054 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2055 if (status < 0)
2056 goto error;
2057 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2058 if (status < 0)
2059 goto error;
2060 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2061 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2062 if (state->m_insertRSByte == true) {
2063 /* enable parity symbol forward */
2064 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2065 /* MVAL disable during parity bytes */
2066 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2067 /* TS burst length to 204 */
2068 fecOcDtoBurstLen = 204;
2069 }
2070
2071 /* Check serial or parrallel output */
2072 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2073 if (state->m_enableParallel == false) {
2074 /* MPEG data output is serial -> set ipr_mode[0] */
2075 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2076 }
2077
2078 switch (oMode) {
2079 case OM_DVBT:
2080 maxBitRate = state->m_DVBTBitrate;
2081 fecOcTmdMode = 3;
2082 fecOcRcnCtlRate = 0xC00000;
2083 staticCLK = state->m_DVBTStaticCLK;
2084 break;
2085 case OM_QAM_ITU_A: /* fallthrough */
2086 case OM_QAM_ITU_C:
2087 fecOcTmdMode = 0x0004;
2088 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2089 maxBitRate = state->m_DVBCBitrate;
2090 staticCLK = state->m_DVBCStaticCLK;
2091 break;
2092 default:
2093 status = -EINVAL;
2094 } /* switch (standard) */
2095 if (status < 0)
2096 goto error;
2097
2098 /* Configure DTO's */
2099 if (staticCLK) {
2100 u32 bitRate = 0;
2101
2102 /* Rational DTO for MCLK source (static MCLK rate),
2103 Dynamic DTO for optimal grouping
2104 (avoid intra-packet gaps),
2105 DTO offset enable to sync TS burst with MSTRT */
2106 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2107 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2108 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2109 FEC_OC_FCT_MODE_VIRT_ENA__M);
2110
2111 /* Check user defined bitrate */
2112 bitRate = maxBitRate;
2113 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2114 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002115 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002116 /* Rational DTO period:
2117 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002118
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002119 Result should be floored,
2120 to make sure >= requested bitrate
2121 */
2122 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2123 * 1000) / bitRate);
2124 if (fecOcDtoPeriod <= 2)
2125 fecOcDtoPeriod = 0;
2126 else
2127 fecOcDtoPeriod -= 2;
2128 fecOcTmdIntUpdRate = 8;
2129 } else {
2130 /* (commonAttr->staticCLK == false) => dynamic mode */
2131 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2132 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2133 fecOcTmdIntUpdRate = 5;
2134 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002135
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002136 /* Write appropriate registers with requested configuration */
2137 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2138 if (status < 0)
2139 goto error;
2140 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2141 if (status < 0)
2142 goto error;
2143 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2144 if (status < 0)
2145 goto error;
2146 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2147 if (status < 0)
2148 goto error;
2149 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2150 if (status < 0)
2151 goto error;
2152 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2153 if (status < 0)
2154 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002155
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002156 /* Rate integration settings */
2157 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2158 if (status < 0)
2159 goto error;
2160 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2161 if (status < 0)
2162 goto error;
2163 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2164error:
2165 if (status < 0)
2166 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002167 return status;
2168}
2169
2170static int MPEGTSConfigurePolarity(struct drxk_state *state)
2171{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002172 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002173
2174 /* Data mask for the output data byte */
2175 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002176 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2177 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2178 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2179 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002180
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002181 dprintk(1, "\n");
2182
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002183 /* Control selective inversion of output bits */
2184 fecOcRegIprInvert &= (~(InvertDataMask));
2185 if (state->m_invertDATA == true)
2186 fecOcRegIprInvert |= InvertDataMask;
2187 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2188 if (state->m_invertERR == true)
2189 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2190 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2191 if (state->m_invertSTR == true)
2192 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2193 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2194 if (state->m_invertVAL == true)
2195 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2196 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2197 if (state->m_invertCLK == true)
2198 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002199
2200 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002201}
2202
2203#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2204
2205static int SetAgcRf(struct drxk_state *state,
2206 struct SCfgAgc *pAgcCfg, bool isDTV)
2207{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002208 int status = -EINVAL;
2209 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002210 struct SCfgAgc *pIfAgcSettings;
2211
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002212 dprintk(1, "\n");
2213
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002214 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002215 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002216
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002217 switch (pAgcCfg->ctrlMode) {
2218 case DRXK_AGC_CTRL_AUTO:
2219 /* Enable RF AGC DAC */
2220 status = read16(state, IQM_AF_STDBY__A, &data);
2221 if (status < 0)
2222 goto error;
2223 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2224 status = write16(state, IQM_AF_STDBY__A, data);
2225 if (status < 0)
2226 goto error;
2227 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2228 if (status < 0)
2229 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002230
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002231 /* Enable SCU RF AGC loop */
2232 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002233
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002234 /* Polarity */
2235 if (state->m_RfAgcPol)
2236 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2237 else
2238 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2239 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2240 if (status < 0)
2241 goto error;
2242
2243 /* Set speed (using complementary reduction value) */
2244 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2245 if (status < 0)
2246 goto error;
2247
2248 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2249 data |= (~(pAgcCfg->speed <<
2250 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2251 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2252
2253 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2254 if (status < 0)
2255 goto error;
2256
2257 if (IsDVBT(state))
2258 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2259 else if (IsQAM(state))
2260 pIfAgcSettings = &state->m_qamIfAgcCfg;
2261 else
2262 pIfAgcSettings = &state->m_atvIfAgcCfg;
2263 if (pIfAgcSettings == NULL) {
2264 status = -EINVAL;
2265 goto error;
2266 }
2267
2268 /* Set TOP, only if IF-AGC is in AUTO mode */
2269 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2270 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002271 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002272 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002273
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002274 /* Cut-Off current */
2275 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2276 if (status < 0)
2277 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002278
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002279 /* Max. output level */
2280 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2281 if (status < 0)
2282 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002283
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002284 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002285
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002286 case DRXK_AGC_CTRL_USER:
2287 /* Enable RF AGC DAC */
2288 status = read16(state, IQM_AF_STDBY__A, &data);
2289 if (status < 0)
2290 goto error;
2291 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2292 status = write16(state, IQM_AF_STDBY__A, data);
2293 if (status < 0)
2294 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002295
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002296 /* Disable SCU RF AGC loop */
2297 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2298 if (status < 0)
2299 goto error;
2300 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2301 if (state->m_RfAgcPol)
2302 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2303 else
2304 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2305 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2306 if (status < 0)
2307 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002308
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002309 /* SCU c.o.c. to 0, enabling full control range */
2310 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2311 if (status < 0)
2312 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002313
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002314 /* Write value to output pin */
2315 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2316 if (status < 0)
2317 goto error;
2318 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002319
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002320 case DRXK_AGC_CTRL_OFF:
2321 /* Disable RF AGC DAC */
2322 status = read16(state, IQM_AF_STDBY__A, &data);
2323 if (status < 0)
2324 goto error;
2325 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2326 status = write16(state, IQM_AF_STDBY__A, data);
2327 if (status < 0)
2328 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002329
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002330 /* Disable SCU RF AGC loop */
2331 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2332 if (status < 0)
2333 goto error;
2334 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2335 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2336 if (status < 0)
2337 goto error;
2338 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002339
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002340 default:
2341 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002342
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002343 }
2344error:
2345 if (status < 0)
2346 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002347 return status;
2348}
2349
2350#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2351
Oliver Endrissebc7de22011-07-03 13:49:44 -03002352static int SetAgcIf(struct drxk_state *state,
2353 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002354{
2355 u16 data = 0;
2356 int status = 0;
2357 struct SCfgAgc *pRfAgcSettings;
2358
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002359 dprintk(1, "\n");
2360
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002361 switch (pAgcCfg->ctrlMode) {
2362 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002363
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002364 /* Enable IF AGC DAC */
2365 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002366 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002367 goto error;
2368 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2369 status = write16(state, IQM_AF_STDBY__A, data);
2370 if (status < 0)
2371 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002372
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002373 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2374 if (status < 0)
2375 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002376
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002377 /* Enable SCU IF AGC loop */
2378 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2379
2380 /* Polarity */
2381 if (state->m_IfAgcPol)
2382 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2383 else
2384 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2385 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2386 if (status < 0)
2387 goto error;
2388
2389 /* Set speed (using complementary reduction value) */
2390 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2391 if (status < 0)
2392 goto error;
2393 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2394 data |= (~(pAgcCfg->speed <<
2395 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2396 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2397
2398 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2399 if (status < 0)
2400 goto error;
2401
2402 if (IsQAM(state))
2403 pRfAgcSettings = &state->m_qamRfAgcCfg;
2404 else
2405 pRfAgcSettings = &state->m_atvRfAgcCfg;
2406 if (pRfAgcSettings == NULL)
2407 return -1;
2408 /* Restore TOP */
2409 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2410 if (status < 0)
2411 goto error;
2412 break;
2413
2414 case DRXK_AGC_CTRL_USER:
2415
2416 /* Enable IF AGC DAC */
2417 status = read16(state, IQM_AF_STDBY__A, &data);
2418 if (status < 0)
2419 goto error;
2420 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2421 status = write16(state, IQM_AF_STDBY__A, data);
2422 if (status < 0)
2423 goto error;
2424
2425 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2426 if (status < 0)
2427 goto error;
2428
2429 /* Disable SCU IF AGC loop */
2430 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2431
2432 /* Polarity */
2433 if (state->m_IfAgcPol)
2434 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2435 else
2436 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2437 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2438 if (status < 0)
2439 goto error;
2440
2441 /* Write value to output pin */
2442 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2443 if (status < 0)
2444 goto error;
2445 break;
2446
2447 case DRXK_AGC_CTRL_OFF:
2448
2449 /* Disable If AGC DAC */
2450 status = read16(state, IQM_AF_STDBY__A, &data);
2451 if (status < 0)
2452 goto error;
2453 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2454 status = write16(state, IQM_AF_STDBY__A, data);
2455 if (status < 0)
2456 goto error;
2457
2458 /* Disable SCU IF AGC loop */
2459 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2460 if (status < 0)
2461 goto error;
2462 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2463 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2464 if (status < 0)
2465 goto error;
2466 break;
2467 } /* switch (agcSettingsIf->ctrlMode) */
2468
2469 /* always set the top to support
2470 configurations without if-loop */
2471 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2472error:
2473 if (status < 0)
2474 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002475 return status;
2476}
2477
2478static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2479{
2480 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002481 int status;
2482 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002483
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002484 dprintk(1, "\n");
2485
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002486 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2487 if (status < 0) {
2488 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2489 return status;
2490 }
2491
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002492 *pValue = 0;
2493
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002494 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2495 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2496 if (Level < 14000)
2497 *pValue = (14000 - Level) / 4;
2498 else
2499 *pValue = 0;
2500
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002501 return status;
2502}
2503
Oliver Endrissebc7de22011-07-03 13:49:44 -03002504static int GetQAMSignalToNoise(struct drxk_state *state,
2505 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002506{
2507 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002508 u16 qamSlErrPower = 0; /* accum. error between
2509 raw and sliced symbols */
2510 u32 qamSlSigPower = 0; /* used for MER, depends of
2511 QAM constellation */
2512 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002513
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002514 dprintk(1, "\n");
2515
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002516 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002517
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002518 /* get the register value needed for MER */
2519 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2520 if (status < 0) {
2521 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2522 return -EINVAL;
2523 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002524
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002525 switch (state->param.u.qam.modulation) {
2526 case QAM_16:
2527 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2528 break;
2529 case QAM_32:
2530 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2531 break;
2532 case QAM_64:
2533 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2534 break;
2535 case QAM_128:
2536 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2537 break;
2538 default:
2539 case QAM_256:
2540 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2541 break;
2542 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002543
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002544 if (qamSlErrPower > 0) {
2545 qamSlMer = Log10Times100(qamSlSigPower) -
2546 Log10Times100((u32) qamSlErrPower);
2547 }
2548 *pSignalToNoise = qamSlMer;
2549
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002550 return status;
2551}
2552
Oliver Endrissebc7de22011-07-03 13:49:44 -03002553static int GetDVBTSignalToNoise(struct drxk_state *state,
2554 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002555{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002556 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002557 u16 regData = 0;
2558 u32 EqRegTdSqrErrI = 0;
2559 u32 EqRegTdSqrErrQ = 0;
2560 u16 EqRegTdSqrErrExp = 0;
2561 u16 EqRegTdTpsPwrOfs = 0;
2562 u16 EqRegTdReqSmbCnt = 0;
2563 u32 tpsCnt = 0;
2564 u32 SqrErrIQ = 0;
2565 u32 a = 0;
2566 u32 b = 0;
2567 u32 c = 0;
2568 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002569 u16 transmissionParams = 0;
2570
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002571 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002572
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002573 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2574 if (status < 0)
2575 goto error;
2576 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2577 if (status < 0)
2578 goto error;
2579 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2580 if (status < 0)
2581 goto error;
2582 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2583 if (status < 0)
2584 goto error;
2585 /* Extend SQR_ERR_I operational range */
2586 EqRegTdSqrErrI = (u32) regData;
2587 if ((EqRegTdSqrErrExp > 11) &&
2588 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2589 EqRegTdSqrErrI += 0x00010000UL;
2590 }
2591 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2592 if (status < 0)
2593 goto error;
2594 /* Extend SQR_ERR_Q operational range */
2595 EqRegTdSqrErrQ = (u32) regData;
2596 if ((EqRegTdSqrErrExp > 11) &&
2597 (EqRegTdSqrErrQ < 0x00000FFFUL))
2598 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002599
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002600 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2601 if (status < 0)
2602 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002603
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002604 /* Check input data for MER */
2605
2606 /* MER calculation (in 0.1 dB) without math.h */
2607 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2608 iMER = 0;
2609 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2610 /* No error at all, this must be the HW reset value
2611 * Apparently no first measurement yet
2612 * Set MER to 0.0 */
2613 iMER = 0;
2614 } else {
2615 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2616 EqRegTdSqrErrExp;
2617 if ((transmissionParams &
2618 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2619 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2620 tpsCnt = 17;
2621 else
2622 tpsCnt = 68;
2623
2624 /* IMER = 100 * log10 (x)
2625 where x = (EqRegTdTpsPwrOfs^2 *
2626 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2627
2628 => IMER = a + b -c
2629 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2630 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2631 c = 100 * log10 (SqrErrIQ)
2632 */
2633
2634 /* log(x) x = 9bits * 9bits->18 bits */
2635 a = Log10Times100(EqRegTdTpsPwrOfs *
2636 EqRegTdTpsPwrOfs);
2637 /* log(x) x = 16bits * 7bits->23 bits */
2638 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2639 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2640 c = Log10Times100(SqrErrIQ);
2641
2642 iMER = a + b;
2643 /* No negative MER, clip to zero */
2644 if (iMER > c)
2645 iMER -= c;
2646 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002647 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002648 }
2649 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002650
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002651error:
2652 if (status < 0)
2653 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002654 return status;
2655}
2656
2657static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2658{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002659 dprintk(1, "\n");
2660
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002661 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002662 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002663 case OM_DVBT:
2664 return GetDVBTSignalToNoise(state, pSignalToNoise);
2665 case OM_QAM_ITU_A:
2666 case OM_QAM_ITU_C:
2667 return GetQAMSignalToNoise(state, pSignalToNoise);
2668 default:
2669 break;
2670 }
2671 return 0;
2672}
2673
2674#if 0
2675static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2676{
2677 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2678 int status = 0;
2679
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002680 dprintk(1, "\n");
2681
Oliver Endrissebc7de22011-07-03 13:49:44 -03002682 static s32 QE_SN[] = {
2683 51, /* QPSK 1/2 */
2684 69, /* QPSK 2/3 */
2685 79, /* QPSK 3/4 */
2686 89, /* QPSK 5/6 */
2687 97, /* QPSK 7/8 */
2688 108, /* 16-QAM 1/2 */
2689 131, /* 16-QAM 2/3 */
2690 146, /* 16-QAM 3/4 */
2691 156, /* 16-QAM 5/6 */
2692 160, /* 16-QAM 7/8 */
2693 165, /* 64-QAM 1/2 */
2694 187, /* 64-QAM 2/3 */
2695 202, /* 64-QAM 3/4 */
2696 216, /* 64-QAM 5/6 */
2697 225, /* 64-QAM 7/8 */
2698 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002699
2700 *pQuality = 0;
2701
2702 do {
2703 s32 SignalToNoise = 0;
2704 u16 Constellation = 0;
2705 u16 CodeRate = 0;
2706 u32 SignalToNoiseRel;
2707 u32 BERQuality;
2708
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002709 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2710 if (status < 0)
2711 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002712 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002713 if (status < 0)
2714 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002715 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2716
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002717 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002718 if (status < 0)
2719 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002720 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2721
2722 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2723 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2724 break;
2725 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002726 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002727 BERQuality = 100;
2728
Oliver Endrissebc7de22011-07-03 13:49:44 -03002729 if (SignalToNoiseRel < -70)
2730 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002731 else if (SignalToNoiseRel < 30)
2732 *pQuality = ((SignalToNoiseRel + 70) *
2733 BERQuality) / 100;
2734 else
2735 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002736 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002737 return 0;
2738};
2739
Oliver Endrissebc7de22011-07-03 13:49:44 -03002740static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002741{
2742 int status = 0;
2743 *pQuality = 0;
2744
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002745 dprintk(1, "\n");
2746
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002747 do {
2748 u32 SignalToNoise = 0;
2749 u32 BERQuality = 100;
2750 u32 SignalToNoiseRel = 0;
2751
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002752 status = GetQAMSignalToNoise(state, &SignalToNoise);
2753 if (status < 0)
2754 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002755
Oliver Endrissebc7de22011-07-03 13:49:44 -03002756 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002757 case QAM_16:
2758 SignalToNoiseRel = SignalToNoise - 200;
2759 break;
2760 case QAM_32:
2761 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002762 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002763 case QAM_64:
2764 SignalToNoiseRel = SignalToNoise - 260;
2765 break;
2766 case QAM_128:
2767 SignalToNoiseRel = SignalToNoise - 290;
2768 break;
2769 default:
2770 case QAM_256:
2771 SignalToNoiseRel = SignalToNoise - 320;
2772 break;
2773 }
2774
2775 if (SignalToNoiseRel < -70)
2776 *pQuality = 0;
2777 else if (SignalToNoiseRel < 30)
2778 *pQuality = ((SignalToNoiseRel + 70) *
2779 BERQuality) / 100;
2780 else
2781 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002782 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002783
2784 return status;
2785}
2786
2787static int GetQuality(struct drxk_state *state, s32 *pQuality)
2788{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002789 dprintk(1, "\n");
2790
Oliver Endrissebc7de22011-07-03 13:49:44 -03002791 switch (state->m_OperationMode) {
2792 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002793 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002794 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002795 return GetDVBCQuality(state, pQuality);
2796 default:
2797 break;
2798 }
2799
2800 return 0;
2801}
2802#endif
2803
2804/* Free data ram in SIO HI */
2805#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2806#define SIO_HI_RA_RAM_USR_END__A 0x420060
2807
2808#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2809#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2810#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2811#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2812
2813#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2814#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2815#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2816
2817static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2818{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002819 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002820
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002821 dprintk(1, "\n");
2822
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002823 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002824 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002825 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002826 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002827
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002828 if (state->no_i2c_bridge)
2829 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002830
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002831 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2832 if (status < 0)
2833 goto error;
2834 if (bEnableBridge) {
2835 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 -03002836 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002837 goto error;
2838 } else {
2839 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2840 if (status < 0)
2841 goto error;
2842 }
2843
2844 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2845
2846error:
2847 if (status < 0)
2848 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002849 return status;
2850}
2851
Oliver Endrissebc7de22011-07-03 13:49:44 -03002852static int SetPreSaw(struct drxk_state *state,
2853 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002854{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002855 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002856
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002857 dprintk(1, "\n");
2858
Oliver Endrissebc7de22011-07-03 13:49:44 -03002859 if ((pPreSawCfg == NULL)
2860 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002861 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002862
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002863 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002864error:
2865 if (status < 0)
2866 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002867 return status;
2868}
2869
2870static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002871 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002872{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002873 u16 blStatus = 0;
2874 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2875 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2876 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002877 unsigned long end;
2878
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002879 dprintk(1, "\n");
2880
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002881 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002882 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2883 if (status < 0)
2884 goto error;
2885 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2886 if (status < 0)
2887 goto error;
2888 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2889 if (status < 0)
2890 goto error;
2891 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2892 if (status < 0)
2893 goto error;
2894 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2895 if (status < 0)
2896 goto error;
2897 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2898 if (status < 0)
2899 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002900
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002901 end = jiffies + msecs_to_jiffies(timeOut);
2902 do {
2903 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2904 if (status < 0)
2905 goto error;
2906 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2907 if (blStatus == 0x1) {
2908 printk(KERN_ERR "drxk: SIO not ready\n");
2909 status = -EINVAL;
2910 goto error2;
2911 }
2912error:
2913 if (status < 0)
2914 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2915error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002916 mutex_unlock(&state->mutex);
2917 return status;
2918
2919}
2920
Oliver Endrissebc7de22011-07-03 13:49:44 -03002921static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002922{
2923 u16 data = 0;
2924 int status;
2925
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002926 dprintk(1, "\n");
2927
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002928 /* Start measurement */
2929 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2930 if (status < 0)
2931 goto error;
2932 status = write16(state, IQM_AF_START_LOCK__A, 1);
2933 if (status < 0)
2934 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002935
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002936 *count = 0;
2937 status = read16(state, IQM_AF_PHASE0__A, &data);
2938 if (status < 0)
2939 goto error;
2940 if (data == 127)
2941 *count = *count + 1;
2942 status = read16(state, IQM_AF_PHASE1__A, &data);
2943 if (status < 0)
2944 goto error;
2945 if (data == 127)
2946 *count = *count + 1;
2947 status = read16(state, IQM_AF_PHASE2__A, &data);
2948 if (status < 0)
2949 goto error;
2950 if (data == 127)
2951 *count = *count + 1;
2952
2953error:
2954 if (status < 0)
2955 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002956 return status;
2957}
2958
2959static int ADCSynchronization(struct drxk_state *state)
2960{
2961 u16 count = 0;
2962 int status;
2963
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002964 dprintk(1, "\n");
2965
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002966 status = ADCSyncMeasurement(state, &count);
2967 if (status < 0)
2968 goto error;
2969
2970 if (count == 1) {
2971 /* Try sampling on a diffrent edge */
2972 u16 clkNeg = 0;
2973
2974 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2975 if (status < 0)
2976 goto error;
2977 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2978 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2979 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2980 clkNeg |=
2981 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2982 } else {
2983 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2984 clkNeg |=
2985 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2986 }
2987 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2988 if (status < 0)
2989 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002990 status = ADCSyncMeasurement(state, &count);
2991 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002992 goto error;
2993 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002994
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002995 if (count < 2)
2996 status = -EINVAL;
2997error:
2998 if (status < 0)
2999 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003000 return status;
3001}
3002
3003static int SetFrequencyShifter(struct drxk_state *state,
3004 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003005 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003006{
3007 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003008 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003009 u32 fmFrequencyShift = 0;
3010 bool tunerMirror = !state->m_bMirrorFreqSpect;
3011 u32 adcFreq;
3012 bool adcFlip;
3013 int status;
3014 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003015 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003016 u32 frequencyShift;
3017 bool imageToSelect;
3018
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003019 dprintk(1, "\n");
3020
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003021 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003022 Program frequency shifter
3023 No need to account for mirroring on RF
3024 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003025 if (isDTV) {
3026 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3027 (state->m_OperationMode == OM_QAM_ITU_C) ||
3028 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003029 selectPosImage = true;
3030 else
3031 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003032 }
3033 if (tunerMirror)
3034 /* tuner doesn't mirror */
3035 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003036 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003037 else
3038 /* tuner mirrors */
3039 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003040 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003041 if (ifFreqActual > samplingFrequency / 2) {
3042 /* adc mirrors */
3043 adcFreq = samplingFrequency - ifFreqActual;
3044 adcFlip = true;
3045 } else {
3046 /* adc doesn't mirror */
3047 adcFreq = ifFreqActual;
3048 adcFlip = false;
3049 }
3050
3051 frequencyShift = adcFreq;
3052 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003053 adcFlip ^ selectPosImage;
3054 state->m_IqmFsRateOfs =
3055 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003056
3057 if (imageToSelect)
3058 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3059
3060 /* Program frequency shifter with tuner offset compensation */
3061 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003062 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3063 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003064 if (status < 0)
3065 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003066 return status;
3067}
3068
3069static int InitAGC(struct drxk_state *state, bool isDTV)
3070{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003071 u16 ingainTgt = 0;
3072 u16 ingainTgtMin = 0;
3073 u16 ingainTgtMax = 0;
3074 u16 clpCyclen = 0;
3075 u16 clpSumMin = 0;
3076 u16 clpDirTo = 0;
3077 u16 snsSumMin = 0;
3078 u16 snsSumMax = 0;
3079 u16 clpSumMax = 0;
3080 u16 snsDirTo = 0;
3081 u16 kiInnergainMin = 0;
3082 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003083 u16 ifIaccuHiTgtMin = 0;
3084 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003085 u16 data = 0;
3086 u16 fastClpCtrlDelay = 0;
3087 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003088 int status = 0;
3089
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003090 dprintk(1, "\n");
3091
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003092 /* Common settings */
3093 snsSumMax = 1023;
3094 ifIaccuHiTgtMin = 2047;
3095 clpCyclen = 500;
3096 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003097
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003098 /* AGCInit() not available for DVBT; init done in microcode */
3099 if (!IsQAM(state)) {
3100 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3101 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003102 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003103
3104 /* FIXME: Analog TV AGC require different settings */
3105
3106 /* Standard specific settings */
3107 clpSumMin = 8;
3108 clpDirTo = (u16) -9;
3109 clpCtrlMode = 0;
3110 snsSumMin = 8;
3111 snsDirTo = (u16) -9;
3112 kiInnergainMin = (u16) -1030;
3113 ifIaccuHiTgtMax = 0x2380;
3114 ifIaccuHiTgt = 0x2380;
3115 ingainTgtMin = 0x0511;
3116 ingainTgt = 0x0511;
3117 ingainTgtMax = 5119;
3118 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3119
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003120 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3121 if (status < 0)
3122 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003123
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003124 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3125 if (status < 0)
3126 goto error;
3127 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3128 if (status < 0)
3129 goto error;
3130 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3131 if (status < 0)
3132 goto error;
3133 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3134 if (status < 0)
3135 goto error;
3136 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3137 if (status < 0)
3138 goto error;
3139 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3140 if (status < 0)
3141 goto error;
3142 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3143 if (status < 0)
3144 goto error;
3145 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3146 if (status < 0)
3147 goto error;
3148 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3149 if (status < 0)
3150 goto error;
3151 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3152 if (status < 0)
3153 goto error;
3154 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3155 if (status < 0)
3156 goto error;
3157 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3158 if (status < 0)
3159 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003160
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003161 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3162 if (status < 0)
3163 goto error;
3164 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3165 if (status < 0)
3166 goto error;
3167 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3168 if (status < 0)
3169 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003170
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003171 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3172 if (status < 0)
3173 goto error;
3174 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3175 if (status < 0)
3176 goto error;
3177 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3178 if (status < 0)
3179 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003180
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003181 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3182 if (status < 0)
3183 goto error;
3184 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3185 if (status < 0)
3186 goto error;
3187 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3188 if (status < 0)
3189 goto error;
3190 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3191 if (status < 0)
3192 goto error;
3193 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3194 if (status < 0)
3195 goto error;
3196 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3197 if (status < 0)
3198 goto error;
3199 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3200 if (status < 0)
3201 goto error;
3202 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3203 if (status < 0)
3204 goto error;
3205 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3206 if (status < 0)
3207 goto error;
3208 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3209 if (status < 0)
3210 goto error;
3211 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3212 if (status < 0)
3213 goto error;
3214 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3215 if (status < 0)
3216 goto error;
3217 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3218 if (status < 0)
3219 goto error;
3220 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3221 if (status < 0)
3222 goto error;
3223 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3224 if (status < 0)
3225 goto error;
3226 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3227 if (status < 0)
3228 goto error;
3229 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3230 if (status < 0)
3231 goto error;
3232 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3233 if (status < 0)
3234 goto error;
3235 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3236 if (status < 0)
3237 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003238
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003239 /* Initialize inner-loop KI gain factors */
3240 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3241 if (status < 0)
3242 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003243
3244 data = 0x0657;
3245 data &= ~SCU_RAM_AGC_KI_RF__M;
3246 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3247 data &= ~SCU_RAM_AGC_KI_IF__M;
3248 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3249
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003250 status = write16(state, SCU_RAM_AGC_KI__A, data);
3251error:
3252 if (status < 0)
3253 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003254 return status;
3255}
3256
Oliver Endrissebc7de22011-07-03 13:49:44 -03003257static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003258{
3259 int status;
3260
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003261 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003262 if (packetErr == NULL)
3263 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3264 else
3265 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3266 if (status < 0)
3267 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003268 return status;
3269}
3270
3271static int DVBTScCommand(struct drxk_state *state,
3272 u16 cmd, u16 subcmd,
3273 u16 param0, u16 param1, u16 param2,
3274 u16 param3, u16 param4)
3275{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003276 u16 curCmd = 0;
3277 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003278 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003279 u16 scExec = 0;
3280 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003281
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003282 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003283 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003284 if (scExec != 1) {
3285 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003286 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003287 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003288 if (status < 0)
3289 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003290
3291 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003292 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003293 do {
3294 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003295 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003296 retryCnt++;
3297 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003298 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3299 goto error;
3300
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003301 /* Write sub-command */
3302 switch (cmd) {
3303 /* All commands using sub-cmd */
3304 case OFDM_SC_RA_RAM_CMD_PROC_START:
3305 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3306 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003307 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3308 if (status < 0)
3309 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003310 break;
3311 default:
3312 /* Do nothing */
3313 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003314 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003315
3316 /* Write needed parameters and the command */
3317 switch (cmd) {
3318 /* All commands using 5 parameters */
3319 /* All commands using 4 parameters */
3320 /* All commands using 3 parameters */
3321 /* All commands using 2 parameters */
3322 case OFDM_SC_RA_RAM_CMD_PROC_START:
3323 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3324 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003325 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003326 /* All commands using 1 parameters */
3327 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3328 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003329 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003330 /* All commands using 0 parameters */
3331 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3332 case OFDM_SC_RA_RAM_CMD_NULL:
3333 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003334 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003335 break;
3336 default:
3337 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003338 status = -EINVAL;
3339 }
3340 if (status < 0)
3341 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003342
3343 /* Wait until sc is ready processing command */
3344 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003345 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003346 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003347 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003348 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003349 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003350 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3351 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003352
3353 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003354 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003355 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003356 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003357 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003358 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003359 if (status < 0)
3360 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003361
3362 /* Retreive results parameters from SC */
3363 switch (cmd) {
3364 /* All commands yielding 5 results */
3365 /* All commands yielding 4 results */
3366 /* All commands yielding 3 results */
3367 /* All commands yielding 2 results */
3368 /* All commands yielding 1 result */
3369 case OFDM_SC_RA_RAM_CMD_USER_IO:
3370 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003371 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003372 /* All commands yielding 0 results */
3373 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3374 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3375 case OFDM_SC_RA_RAM_CMD_PROC_START:
3376 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3377 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3378 case OFDM_SC_RA_RAM_CMD_NULL:
3379 break;
3380 default:
3381 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003382 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003383 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003384 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003385error:
3386 if (status < 0)
3387 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003388 return status;
3389}
3390
Oliver Endrissebc7de22011-07-03 13:49:44 -03003391static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003392{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003393 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003394 int status;
3395
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003396 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003397 status = CtrlPowerMode(state, &powerMode);
3398 if (status < 0)
3399 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003400 return status;
3401}
3402
Oliver Endrissebc7de22011-07-03 13:49:44 -03003403static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003404{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003405 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003406
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003407 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003408 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003409 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003410 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003411 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003412 if (status < 0)
3413 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003414 return status;
3415}
3416
3417#define DEFAULT_FR_THRES_8K 4000
3418static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3419{
3420
3421 int status;
3422
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003423 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003424 if (*enabled == true) {
3425 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003426 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003427 DEFAULT_FR_THRES_8K);
3428 } else {
3429 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003430 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003431 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003432 if (status < 0)
3433 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003434
3435 return status;
3436}
3437
3438static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3439 struct DRXKCfgDvbtEchoThres_t *echoThres)
3440{
3441 u16 data = 0;
3442 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003443
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003444 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003445 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3446 if (status < 0)
3447 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003448
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003449 switch (echoThres->fftMode) {
3450 case DRX_FFTMODE_2K:
3451 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3452 data |= ((echoThres->threshold <<
3453 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3454 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3455 goto error;
3456 case DRX_FFTMODE_8K:
3457 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3458 data |= ((echoThres->threshold <<
3459 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3460 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3461 goto error;
3462 default:
3463 return -EINVAL;
3464 goto error;
3465 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003466
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003467 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3468error:
3469 if (status < 0)
3470 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003471 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003472}
3473
3474static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003475 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003476{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003477 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003478
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003479 dprintk(1, "\n");
3480
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003481 switch (*speed) {
3482 case DRXK_DVBT_SQI_SPEED_FAST:
3483 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3484 case DRXK_DVBT_SQI_SPEED_SLOW:
3485 break;
3486 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003487 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003488 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003489 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003490 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003491error:
3492 if (status < 0)
3493 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003494 return status;
3495}
3496
3497/*============================================================================*/
3498
3499/**
3500* \brief Activate DVBT specific presets
3501* \param demod instance of demodulator.
3502* \return DRXStatus_t.
3503*
3504* Called in DVBTSetStandard
3505*
3506*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003507static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003508{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003509 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003510 bool setincenable = false;
3511 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003512
Oliver Endrissebc7de22011-07-03 13:49:44 -03003513 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3514 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003515
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003516 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003517 status = DVBTCtrlSetIncEnable(state, &setincenable);
3518 if (status < 0)
3519 goto error;
3520 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3521 if (status < 0)
3522 goto error;
3523 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3524 if (status < 0)
3525 goto error;
3526 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3527 if (status < 0)
3528 goto error;
3529 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3530error:
3531 if (status < 0)
3532 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003533 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003534}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003535
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003536/*============================================================================*/
3537
3538/**
3539* \brief Initialize channelswitch-independent settings for DVBT.
3540* \param demod instance of demodulator.
3541* \return DRXStatus_t.
3542*
3543* For ROM code channel filter taps are loaded from the bootloader. For microcode
3544* the DVB-T taps from the drxk_filters.h are used.
3545*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003546static int SetDVBTStandard(struct drxk_state *state,
3547 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003548{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003549 u16 cmdResult = 0;
3550 u16 data = 0;
3551 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003552
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003553 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003554
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003555 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003556 /* added antenna switch */
3557 SwitchAntennaToDVBT(state);
3558 /* send OFDM reset command */
3559 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 -03003560 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003561 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003562
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003563 /* send OFDM setenv command */
3564 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3565 if (status < 0)
3566 goto error;
3567
3568 /* reset datapath for OFDM, processors first */
3569 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3570 if (status < 0)
3571 goto error;
3572 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3573 if (status < 0)
3574 goto error;
3575 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3576 if (status < 0)
3577 goto error;
3578
3579 /* IQM setup */
3580 /* synchronize on ofdstate->m_festart */
3581 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3582 if (status < 0)
3583 goto error;
3584 /* window size for clipping ADC detection */
3585 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3586 if (status < 0)
3587 goto error;
3588 /* window size for for sense pre-SAW detection */
3589 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3590 if (status < 0)
3591 goto error;
3592 /* sense threshold for sense pre-SAW detection */
3593 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3594 if (status < 0)
3595 goto error;
3596 status = SetIqmAf(state, true);
3597 if (status < 0)
3598 goto error;
3599
3600 status = write16(state, IQM_AF_AGC_RF__A, 0);
3601 if (status < 0)
3602 goto error;
3603
3604 /* Impulse noise cruncher setup */
3605 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3606 if (status < 0)
3607 goto error;
3608 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3609 if (status < 0)
3610 goto error;
3611 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3612 if (status < 0)
3613 goto error;
3614
3615 status = write16(state, IQM_RC_STRETCH__A, 16);
3616 if (status < 0)
3617 goto error;
3618 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3619 if (status < 0)
3620 goto error;
3621 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3622 if (status < 0)
3623 goto error;
3624 status = write16(state, IQM_CF_SCALE__A, 1600);
3625 if (status < 0)
3626 goto error;
3627 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3628 if (status < 0)
3629 goto error;
3630
3631 /* virtual clipping threshold for clipping ADC detection */
3632 status = write16(state, IQM_AF_CLP_TH__A, 448);
3633 if (status < 0)
3634 goto error;
3635 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3636 if (status < 0)
3637 goto error;
3638
3639 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3640 if (status < 0)
3641 goto error;
3642
3643 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3644 if (status < 0)
3645 goto error;
3646 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3647 if (status < 0)
3648 goto error;
3649 /* enable power measurement interrupt */
3650 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3651 if (status < 0)
3652 goto error;
3653 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3654 if (status < 0)
3655 goto error;
3656
3657 /* IQM will not be reset from here, sync ADC and update/init AGC */
3658 status = ADCSynchronization(state);
3659 if (status < 0)
3660 goto error;
3661 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3662 if (status < 0)
3663 goto error;
3664
3665 /* Halt SCU to enable safe non-atomic accesses */
3666 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3667 if (status < 0)
3668 goto error;
3669
3670 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3671 if (status < 0)
3672 goto error;
3673 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3674 if (status < 0)
3675 goto error;
3676
3677 /* Set Noise Estimation notch width and enable DC fix */
3678 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3679 if (status < 0)
3680 goto error;
3681 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3682 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3683 if (status < 0)
3684 goto error;
3685
3686 /* Activate SCU to enable SCU commands */
3687 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3688 if (status < 0)
3689 goto error;
3690
3691 if (!state->m_DRXK_A3_ROM_CODE) {
3692 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3693 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3694 if (status < 0)
3695 goto error;
3696 }
3697
3698 /* OFDM_SC setup */
3699#ifdef COMPILE_FOR_NONRT
3700 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3701 if (status < 0)
3702 goto error;
3703 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3704 if (status < 0)
3705 goto error;
3706#endif
3707
3708 /* FEC setup */
3709 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3710 if (status < 0)
3711 goto error;
3712
3713
3714#ifdef COMPILE_FOR_NONRT
3715 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3716 if (status < 0)
3717 goto error;
3718#else
3719 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3720 if (status < 0)
3721 goto error;
3722#endif
3723 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3724 if (status < 0)
3725 goto error;
3726
3727 /* Setup MPEG bus */
3728 status = MPEGTSDtoSetup(state, OM_DVBT);
3729 if (status < 0)
3730 goto error;
3731 /* Set DVBT Presets */
3732 status = DVBTActivatePresets(state);
3733 if (status < 0)
3734 goto error;
3735
3736error:
3737 if (status < 0)
3738 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003739 return status;
3740}
3741
3742/*============================================================================*/
3743/**
3744* \brief Start dvbt demodulating for channel.
3745* \param demod instance of demodulator.
3746* \return DRXStatus_t.
3747*/
3748static int DVBTStart(struct drxk_state *state)
3749{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003750 u16 param1;
3751 int status;
3752 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003753
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003754 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003755 /* Start correct processes to get in lock */
3756 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003757 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3758 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3759 if (status < 0)
3760 goto error;
3761 /* Start FEC OC */
3762 status = MPEGTSStart(state);
3763 if (status < 0)
3764 goto error;
3765 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3766 if (status < 0)
3767 goto error;
3768error:
3769 if (status < 0)
3770 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003771 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003772}
3773
3774
3775/*============================================================================*/
3776
3777/**
3778* \brief Set up dvbt demodulator for channel.
3779* \param demod instance of demodulator.
3780* \return DRXStatus_t.
3781* // original DVBTSetChannel()
3782*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003783static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3784 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003785{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003786 u16 cmdResult = 0;
3787 u16 transmissionParams = 0;
3788 u16 operationMode = 0;
3789 u32 iqmRcRateOfs = 0;
3790 u32 bandwidth = 0;
3791 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003792 int status;
3793
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003794 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003795
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003796 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3797 if (status < 0)
3798 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003799
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003800 /* Halt SCU to enable safe non-atomic accesses */
3801 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3802 if (status < 0)
3803 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003804
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003805 /* Stop processors */
3806 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3807 if (status < 0)
3808 goto error;
3809 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3810 if (status < 0)
3811 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003812
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003813 /* Mandatory fix, always stop CP, required to set spl offset back to
3814 hardware default (is set to 0 by ucode during pilot detection */
3815 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3816 if (status < 0)
3817 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003818
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003819 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003820
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003821 /* mode */
3822 switch (state->param.u.ofdm.transmission_mode) {
3823 case TRANSMISSION_MODE_AUTO:
3824 default:
3825 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3826 /* fall through , try first guess DRX_FFTMODE_8K */
3827 case TRANSMISSION_MODE_8K:
3828 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
3829 goto error;
3830 case TRANSMISSION_MODE_2K:
3831 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
3832 goto error;
3833 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003834
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003835 /* guard */
3836 switch (state->param.u.ofdm.guard_interval) {
3837 default:
3838 case GUARD_INTERVAL_AUTO:
3839 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3840 /* fall through , try first guess DRX_GUARD_1DIV4 */
3841 case GUARD_INTERVAL_1_4:
3842 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
3843 goto error;
3844 case GUARD_INTERVAL_1_32:
3845 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
3846 goto error;
3847 case GUARD_INTERVAL_1_16:
3848 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
3849 goto error;
3850 case GUARD_INTERVAL_1_8:
3851 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
3852 goto error;
3853 }
3854
3855 /* hierarchy */
3856 switch (state->param.u.ofdm.hierarchy_information) {
3857 case HIERARCHY_AUTO:
3858 case HIERARCHY_NONE:
3859 default:
3860 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3861 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3862 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3863 /* break; */
3864 case HIERARCHY_1:
3865 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3866 break;
3867 case HIERARCHY_2:
3868 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3869 break;
3870 case HIERARCHY_4:
3871 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3872 break;
3873 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003874
3875
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003876 /* constellation */
3877 switch (state->param.u.ofdm.constellation) {
3878 case QAM_AUTO:
3879 default:
3880 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3881 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3882 case QAM_64:
3883 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3884 break;
3885 case QPSK:
3886 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3887 break;
3888 case QAM_16:
3889 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3890 break;
3891 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003892#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003893 /* No hierachical channels support in BDA */
3894 /* Priority (only for hierarchical channels) */
3895 switch (channel->priority) {
3896 case DRX_PRIORITY_LOW:
3897 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3898 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3899 OFDM_EC_SB_PRIOR_LO);
3900 break;
3901 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003902 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003903 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3904 OFDM_EC_SB_PRIOR_HI));
3905 break;
3906 case DRX_PRIORITY_UNKNOWN: /* fall through */
3907 default:
3908 status = -EINVAL;
3909 goto error;
3910 }
3911#else
3912 /* Set Priorty high */
3913 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3914 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3915 if (status < 0)
3916 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003917#endif
3918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003919 /* coderate */
3920 switch (state->param.u.ofdm.code_rate_HP) {
3921 case FEC_AUTO:
3922 default:
3923 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3924 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3925 case FEC_2_3:
3926 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3927 break;
3928 case FEC_1_2:
3929 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3930 break;
3931 case FEC_3_4:
3932 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3933 break;
3934 case FEC_5_6:
3935 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3936 break;
3937 case FEC_7_8:
3938 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3939 break;
3940 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003941
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003942 /* SAW filter selection: normaly not necesarry, but if wanted
3943 the application can select a SAW filter via the driver by using UIOs */
3944 /* First determine real bandwidth (Hz) */
3945 /* Also set delay for impulse noise cruncher */
3946 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3947 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3948 functions */
3949 switch (state->param.u.ofdm.bandwidth) {
3950 case BANDWIDTH_AUTO:
3951 case BANDWIDTH_8_MHZ:
3952 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;
3970 case BANDWIDTH_7_MHZ:
3971 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;
3989 case BANDWIDTH_6_MHZ:
3990 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.
4196* \param constellation current constellation.
4197* \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,
4205 enum EDrxkConstellation constellation,
4206 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] *
4219 (constellation + 1) *
4220 SyncLoss (== 1) *
4221 ViterbiLoss (==1)
4222 */
4223 switch (constellation) {
4224 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;
5290 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
5291 if (state->param.u.qam.symbol_rate <= 1188750)
5292 ratesel = 3;
5293 else if (state->param.u.qam.symbol_rate <= 2377500)
5294 ratesel = 2;
5295 else if (state->param.u.qam.symbol_rate <= 4755000)
5296 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 */
5304 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5305 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 */
5320 symbFreq = state->param.u.qam.symbol_rate;
5321 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;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005391 u8 parameterLen;
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005392 u16 setEnvParameters[5] = { 0, 0, 0, 0, 0 };
Oliver Endrissebc7de22011-07-03 13:49:44 -03005393 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5394 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005395
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005396 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005397 /*
5398 STEP 1: reset demodulator
5399 resets FEC DI and FEC RS
5400 resets QAM block
5401 resets SCU variables
5402 */
5403 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005404 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005405 goto error;
5406 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5407 if (status < 0)
5408 goto error;
5409 status = QAMResetQAM(state);
5410 if (status < 0)
5411 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005412
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005413 /*
5414 STEP 2: configure demodulator
5415 -set env
5416 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5417 */
5418 status = QAMSetSymbolrate(state);
5419 if (status < 0)
5420 goto error;
5421
5422 /* Env parameters */
5423 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
5424 if (state->m_OperationMode == OM_QAM_ITU_C)
5425 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
5426 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5427 /* check for LOCKRANGE Extented */
5428 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5429 parameterLen = 4;
5430
5431 /* Set params */
5432 switch (state->param.u.qam.modulation) {
5433 case QAM_256:
5434 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5435 break;
5436 case QAM_AUTO:
5437 case QAM_64:
5438 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5439 break;
5440 case QAM_16:
5441 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5442 break;
5443 case QAM_32:
5444 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5445 break;
5446 case QAM_128:
5447 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5448 break;
5449 default:
5450 status = -EINVAL;
5451 break;
5452 }
5453 if (status < 0)
5454 goto error;
5455 setParamParameters[0] = state->m_Constellation; /* constellation */
5456 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5457
5458 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 -03005459 if (status < 0) {
5460 /* Fall-back to the simpler call */
5461 setParamParameters[0] = QAM_TOP_ANNEX_A;
5462 if (state->m_OperationMode == OM_QAM_ITU_C)
5463 setEnvParameters[0] = QAM_TOP_ANNEX_C; /* Annex */
5464 else
5465 setEnvParameters[0] = 0;
5466
5467 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setEnvParameters, 1, &cmdResult);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005468 if (status < 0)
5469 goto error;
5470
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005471 setParamParameters[0] = state->m_Constellation; /* constellation */
5472 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5473
5474 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
5475 }
5476 if (status < 0)
5477 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005478
5479 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5480 setup constellation independent registers */
5481#if 0
5482 status = SetFrequency(channel, tunerFreqOffset));
5483 if (status < 0)
5484 goto error;
5485#endif
5486 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5487 if (status < 0)
5488 goto error;
5489
5490 /* Setup BER measurement */
5491 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5492 if (status < 0)
5493 goto error;
5494
5495 /* Reset default values */
5496 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5497 if (status < 0)
5498 goto error;
5499 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5500 if (status < 0)
5501 goto error;
5502
5503 /* Reset default LC values */
5504 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5505 if (status < 0)
5506 goto error;
5507 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5508 if (status < 0)
5509 goto error;
5510 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5511 if (status < 0)
5512 goto error;
5513 status = write16(state, QAM_LC_MODE__A, 7);
5514 if (status < 0)
5515 goto error;
5516
5517 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5518 if (status < 0)
5519 goto error;
5520 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5521 if (status < 0)
5522 goto error;
5523 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5524 if (status < 0)
5525 goto error;
5526 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5527 if (status < 0)
5528 goto error;
5529 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5530 if (status < 0)
5531 goto error;
5532 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5533 if (status < 0)
5534 goto error;
5535 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5536 if (status < 0)
5537 goto error;
5538 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5539 if (status < 0)
5540 goto error;
5541 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5542 if (status < 0)
5543 goto error;
5544 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5545 if (status < 0)
5546 goto error;
5547 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5548 if (status < 0)
5549 goto error;
5550 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5551 if (status < 0)
5552 goto error;
5553 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5554 if (status < 0)
5555 goto error;
5556 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5557 if (status < 0)
5558 goto error;
5559 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5560 if (status < 0)
5561 goto error;
5562
5563 /* Mirroring, QAM-block starting point not inverted */
5564 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5565 if (status < 0)
5566 goto error;
5567
5568 /* Halt SCU to enable safe non-atomic accesses */
5569 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5570 if (status < 0)
5571 goto error;
5572
5573 /* STEP 4: constellation specific setup */
5574 switch (state->param.u.qam.modulation) {
5575 case QAM_16:
5576 status = SetQAM16(state);
5577 break;
5578 case QAM_32:
5579 status = SetQAM32(state);
5580 break;
5581 case QAM_AUTO:
5582 case QAM_64:
5583 status = SetQAM64(state);
5584 break;
5585 case QAM_128:
5586 status = SetQAM128(state);
5587 break;
5588 case QAM_256:
5589 status = SetQAM256(state);
5590 break;
5591 default:
5592 status = -EINVAL;
5593 break;
5594 }
5595 if (status < 0)
5596 goto error;
5597
5598 /* Activate SCU to enable SCU commands */
5599 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5600 if (status < 0)
5601 goto error;
5602
5603 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5604 /* extAttr->currentChannel.constellation = channel->constellation; */
5605 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5606 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5607 if (status < 0)
5608 goto error;
5609
5610 /* Start processes */
5611 status = MPEGTSStart(state);
5612 if (status < 0)
5613 goto error;
5614 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5615 if (status < 0)
5616 goto error;
5617 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5618 if (status < 0)
5619 goto error;
5620 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5621 if (status < 0)
5622 goto error;
5623
5624 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5625 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5626 if (status < 0)
5627 goto error;
5628
5629 /* update global DRXK data container */
5630/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5631
5632error:
5633 if (status < 0)
5634 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005635 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005636}
5637
Oliver Endrissebc7de22011-07-03 13:49:44 -03005638static int SetQAMStandard(struct drxk_state *state,
5639 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005640{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005641 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005642#ifdef DRXK_QAM_TAPS
5643#define DRXK_QAMA_TAPS_SELECT
5644#include "drxk_filters.h"
5645#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005646#endif
5647
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005648 dprintk(1, "\n");
5649
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005650 /* added antenna switch */
5651 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005652
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005653 /* Ensure correct power-up mode */
5654 status = PowerUpQAM(state);
5655 if (status < 0)
5656 goto error;
5657 /* Reset QAM block */
5658 status = QAMResetQAM(state);
5659 if (status < 0)
5660 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005661
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005662 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005663
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005664 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5665 if (status < 0)
5666 goto error;
5667 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5668 if (status < 0)
5669 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005670
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005671 /* Upload IQM Channel Filter settings by
5672 boot loader from ROM table */
5673 switch (oMode) {
5674 case OM_QAM_ITU_A:
5675 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5676 break;
5677 case OM_QAM_ITU_C:
5678 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 -03005679 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005680 goto error;
5681 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5682 break;
5683 default:
5684 status = -EINVAL;
5685 }
5686 if (status < 0)
5687 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005688
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005689 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5690 if (status < 0)
5691 goto error;
5692 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5693 if (status < 0)
5694 goto error;
5695 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5696 if (status < 0)
5697 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005698
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005699 status = write16(state, IQM_RC_STRETCH__A, 21);
5700 if (status < 0)
5701 goto error;
5702 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5703 if (status < 0)
5704 goto error;
5705 status = write16(state, IQM_AF_CLP_TH__A, 448);
5706 if (status < 0)
5707 goto error;
5708 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5709 if (status < 0)
5710 goto error;
5711 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5712 if (status < 0)
5713 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005714
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005715 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5716 if (status < 0)
5717 goto error;
5718 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5719 if (status < 0)
5720 goto error;
5721 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5722 if (status < 0)
5723 goto error;
5724 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5725 if (status < 0)
5726 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005727
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005728 /* IQM Impulse Noise Processing Unit */
5729 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5730 if (status < 0)
5731 goto error;
5732 status = write16(state, IQM_CF_DATATH__A, 1000);
5733 if (status < 0)
5734 goto error;
5735 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5736 if (status < 0)
5737 goto error;
5738 status = write16(state, IQM_CF_DET_LCT__A, 0);
5739 if (status < 0)
5740 goto error;
5741 status = write16(state, IQM_CF_WND_LEN__A, 1);
5742 if (status < 0)
5743 goto error;
5744 status = write16(state, IQM_CF_PKDTH__A, 1);
5745 if (status < 0)
5746 goto error;
5747 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5748 if (status < 0)
5749 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005750
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005751 /* turn on IQMAF. Must be done before setAgc**() */
5752 status = SetIqmAf(state, true);
5753 if (status < 0)
5754 goto error;
5755 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5756 if (status < 0)
5757 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005758
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005759 /* IQM will not be reset from here, sync ADC and update/init AGC */
5760 status = ADCSynchronization(state);
5761 if (status < 0)
5762 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005763
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005764 /* Set the FSM step period */
5765 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5766 if (status < 0)
5767 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005768
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005769 /* Halt SCU to enable safe non-atomic accesses */
5770 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5771 if (status < 0)
5772 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005773
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005774 /* No more resets of the IQM, current standard correctly set =>
5775 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005776
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005777 status = InitAGC(state, true);
5778 if (status < 0)
5779 goto error;
5780 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5781 if (status < 0)
5782 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005783
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005784 /* Configure AGC's */
5785 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5786 if (status < 0)
5787 goto error;
5788 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5789 if (status < 0)
5790 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005791
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005792 /* Activate SCU to enable SCU commands */
5793 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5794error:
5795 if (status < 0)
5796 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005797 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005798}
5799
5800static int WriteGPIO(struct drxk_state *state)
5801{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005802 int status;
5803 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005804
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005805 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005806 /* stop lock indicator process */
5807 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5808 if (status < 0)
5809 goto error;
5810
5811 /* Write magic word to enable pdr reg write */
5812 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5813 if (status < 0)
5814 goto error;
5815
5816 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005817 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5818 /* write to io pad configuration register - output mode */
5819 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5820 if (status < 0)
5821 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005822
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005823 /* use corresponding bit in io data output registar */
5824 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5825 if (status < 0)
5826 goto error;
5827 if ((state->m_GPIO & 0x0001) == 0)
5828 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5829 else
5830 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5831 /* write back to io data output register */
5832 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5833 if (status < 0)
5834 goto error;
5835 }
5836 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5837 /* write to io pad configuration register - output mode */
5838 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5839 if (status < 0)
5840 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005841
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005842 /* use corresponding bit in io data output registar */
5843 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5844 if (status < 0)
5845 goto error;
5846 if ((state->m_GPIO & 0x0002) == 0)
5847 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5848 else
5849 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5850 /* write back to io data output register */
5851 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5852 if (status < 0)
5853 goto error;
5854 }
5855 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5856 /* write to io pad configuration register - output mode */
5857 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5858 if (status < 0)
5859 goto error;
5860
5861 /* use corresponding bit in io data output registar */
5862 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5863 if (status < 0)
5864 goto error;
5865 if ((state->m_GPIO & 0x0004) == 0)
5866 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5867 else
5868 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5869 /* write back to io data output register */
5870 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5871 if (status < 0)
5872 goto error;
5873 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005874 }
5875 /* Write magic word to disable pdr reg write */
5876 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5877error:
5878 if (status < 0)
5879 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005880 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005881}
5882
5883static int SwitchAntennaToQAM(struct drxk_state *state)
5884{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005885 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005886 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005887
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005888 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005889
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005890 if (!state->antenna_gpio)
5891 return 0;
5892
5893 gpio_state = state->m_GPIO & state->antenna_gpio;
5894
5895 if (state->antenna_dvbt ^ gpio_state) {
5896 /* Antenna is on DVB-T mode. Switch */
5897 if (state->antenna_dvbt)
5898 state->m_GPIO &= ~state->antenna_gpio;
5899 else
5900 state->m_GPIO |= state->antenna_gpio;
5901 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005902 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005903 if (status < 0)
5904 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005905 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005906}
5907
5908static int SwitchAntennaToDVBT(struct drxk_state *state)
5909{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005910 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005911 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005912
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005913 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005914
5915 if (!state->antenna_gpio)
5916 return 0;
5917
5918 gpio_state = state->m_GPIO & state->antenna_gpio;
5919
5920 if (!(state->antenna_dvbt ^ gpio_state)) {
5921 /* Antenna is on DVB-C mode. Switch */
5922 if (state->antenna_dvbt)
5923 state->m_GPIO |= state->antenna_gpio;
5924 else
5925 state->m_GPIO &= ~state->antenna_gpio;
5926 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005927 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005928 if (status < 0)
5929 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005930 return status;
5931}
5932
5933
5934static int PowerDownDevice(struct drxk_state *state)
5935{
5936 /* Power down to requested mode */
5937 /* Backup some register settings */
5938 /* Set pins with possible pull-ups connected to them in input mode */
5939 /* Analog power down */
5940 /* ADC power down */
5941 /* Power down device */
5942 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005943
5944 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005945 if (state->m_bPDownOpenBridge) {
5946 /* Open I2C bridge before power down of DRXK */
5947 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005948 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005949 goto error;
5950 }
5951 /* driver 0.9.0 */
5952 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005953 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005954 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005955
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005956 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5957 if (status < 0)
5958 goto error;
5959 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5960 if (status < 0)
5961 goto error;
5962 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5963 status = HI_CfgCommand(state);
5964error:
5965 if (status < 0)
5966 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5967
5968 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005969}
5970
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005971static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005972{
5973 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005974 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005975
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005976 dprintk(1, "\n");
5977
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005978 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5979 if (err < 0) {
5980 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005981 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005982 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005983 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005984 return err;
5985 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005986 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005987 release_firmware(fw);
5988 return err;
5989}
5990
5991static int init_drxk(struct drxk_state *state)
5992{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005993 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005994 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005995 u16 driverVersion;
5996
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005997 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005998 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005999 status = PowerUpDevice(state);
6000 if (status < 0)
6001 goto error;
6002 status = DRXX_Open(state);
6003 if (status < 0)
6004 goto error;
6005 /* Soft reset of OFDM-, sys- and osc-clockdomain */
6006 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);
6007 if (status < 0)
6008 goto error;
6009 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6010 if (status < 0)
6011 goto error;
6012 /* TODO is this needed, if yes how much delay in worst case scenario */
6013 msleep(1);
6014 state->m_DRXK_A3_PATCH_CODE = true;
6015 status = GetDeviceCapabilities(state);
6016 if (status < 0)
6017 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006018
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006019 /* Bridge delay, uses oscilator clock */
6020 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6021 /* SDA brdige delay */
6022 state->m_HICfgBridgeDelay =
6023 (u16) ((state->m_oscClockFreq / 1000) *
6024 HI_I2C_BRIDGE_DELAY) / 1000;
6025 /* Clipping */
6026 if (state->m_HICfgBridgeDelay >
6027 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006028 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006029 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6030 }
6031 /* SCL bridge delay, same as SDA for now */
6032 state->m_HICfgBridgeDelay +=
6033 state->m_HICfgBridgeDelay <<
6034 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006035
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006036 status = InitHI(state);
6037 if (status < 0)
6038 goto error;
6039 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006040#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006041 if (!(state->m_DRXK_A1_ROM_CODE)
6042 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006043#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006044 {
6045 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6046 if (status < 0)
6047 goto error;
6048 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006049
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006050 /* disable MPEG port */
6051 status = MPEGTSDisable(state);
6052 if (status < 0)
6053 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006054
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006055 /* Stop AUD and SCU */
6056 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6057 if (status < 0)
6058 goto error;
6059 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6060 if (status < 0)
6061 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006062
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006063 /* enable token-ring bus through OFDM block for possible ucode upload */
6064 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6065 if (status < 0)
6066 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006067
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006068 /* include boot loader section */
6069 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6070 if (status < 0)
6071 goto error;
6072 status = BLChainCmd(state, 0, 6, 100);
6073 if (status < 0)
6074 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006076 if (!state->microcode_name)
6077 load_microcode(state, "drxk_a3.mc");
6078 else
6079 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006080
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006081 /* disable token-ring bus through OFDM block for possible ucode upload */
6082 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6083 if (status < 0)
6084 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006085
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006086 /* Run SCU for a little while to initialize microcode version numbers */
6087 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6088 if (status < 0)
6089 goto error;
6090 status = DRXX_Open(state);
6091 if (status < 0)
6092 goto error;
6093 /* added for test */
6094 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006095
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006096 powerMode = DRXK_POWER_DOWN_OFDM;
6097 status = CtrlPowerMode(state, &powerMode);
6098 if (status < 0)
6099 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006100
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006101 /* Stamp driver version number in SCU data RAM in BCD code
6102 Done to enable field application engineers to retreive drxdriver version
6103 via I2C from SCU RAM.
6104 Not using SCU command interface for SCU register access since no
6105 microcode may be present.
6106 */
6107 driverVersion =
6108 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6109 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6110 ((DRXK_VERSION_MAJOR % 10) << 4) +
6111 (DRXK_VERSION_MINOR % 10);
6112 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6113 if (status < 0)
6114 goto error;
6115 driverVersion =
6116 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6117 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6118 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6119 (DRXK_VERSION_PATCH % 10);
6120 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6121 if (status < 0)
6122 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006123
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006124 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6125 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6126 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006127
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006128 /* Dirty fix of default values for ROM/PATCH microcode
6129 Dirty because this fix makes it impossible to setup suitable values
6130 before calling DRX_Open. This solution requires changes to RF AGC speed
6131 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006132
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006133 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006134
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006135 /* Reset driver debug flags to 0 */
6136 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6137 if (status < 0)
6138 goto error;
6139 /* driver 0.9.0 */
6140 /* Setup FEC OC:
6141 NOTE: No more full FEC resets allowed afterwards!! */
6142 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6143 if (status < 0)
6144 goto error;
6145 /* MPEGTS functions are still the same */
6146 status = MPEGTSDtoInit(state);
6147 if (status < 0)
6148 goto error;
6149 status = MPEGTSStop(state);
6150 if (status < 0)
6151 goto error;
6152 status = MPEGTSConfigurePolarity(state);
6153 if (status < 0)
6154 goto error;
6155 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6156 if (status < 0)
6157 goto error;
6158 /* added: configure GPIO */
6159 status = WriteGPIO(state);
6160 if (status < 0)
6161 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006162
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006163 state->m_DrxkState = DRXK_STOPPED;
6164
6165 if (state->m_bPowerDown) {
6166 status = PowerDownDevice(state);
6167 if (status < 0)
6168 goto error;
6169 state->m_DrxkState = DRXK_POWERED_DOWN;
6170 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006171 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006172 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006173error:
6174 if (status < 0)
6175 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006176
6177 return 0;
6178}
6179
Oliver Endrissebc7de22011-07-03 13:49:44 -03006180static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006181{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006182 struct drxk_state *state = fe->demodulator_priv;
6183
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006184 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006185 kfree(state);
6186}
6187
Oliver Endrissebc7de22011-07-03 13:49:44 -03006188static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006189{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006190 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006191
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006192 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006193 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006194 return -EBUSY;
6195 SetOperationMode(state, OM_QAM_ITU_A);
6196 return 0;
6197}
6198
Oliver Endrissebc7de22011-07-03 13:49:44 -03006199static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006200{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006201 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006202
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006203 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006204 ShutDown(state);
6205 mutex_unlock(&state->ctlock);
6206 return 0;
6207}
6208
Oliver Endrissebc7de22011-07-03 13:49:44 -03006209static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006210{
6211 struct drxk_state *state = fe->demodulator_priv;
6212
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006213 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006214 return ConfigureI2CBridge(state, enable ? true : false);
6215}
6216
Oliver Endrissebc7de22011-07-03 13:49:44 -03006217static int drxk_set_parameters(struct dvb_frontend *fe,
6218 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006219{
6220 struct drxk_state *state = fe->demodulator_priv;
6221 u32 IF;
6222
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006223 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006224 if (fe->ops.i2c_gate_ctrl)
6225 fe->ops.i2c_gate_ctrl(fe, 1);
6226 if (fe->ops.tuner_ops.set_params)
6227 fe->ops.tuner_ops.set_params(fe, p);
6228 if (fe->ops.i2c_gate_ctrl)
6229 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006230 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006231 fe->ops.tuner_ops.get_frequency(fe, &IF);
6232 Start(state, 0, IF);
6233
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006234 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006235
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006236 return 0;
6237}
6238
Oliver Endrissebc7de22011-07-03 13:49:44 -03006239static int drxk_c_get_frontend(struct dvb_frontend *fe,
6240 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006241{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006242 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006243 return 0;
6244}
6245
6246static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6247{
6248 struct drxk_state *state = fe->demodulator_priv;
6249 u32 stat;
6250
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006251 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006252 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006253 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006254 if (stat == MPEG_LOCK)
6255 *status |= 0x1f;
6256 if (stat == FEC_LOCK)
6257 *status |= 0x0f;
6258 if (stat == DEMOD_LOCK)
6259 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006260 return 0;
6261}
6262
6263static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6264{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006265 dprintk(1, "\n");
6266
Oliver Endrissebc7de22011-07-03 13:49:44 -03006267 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006268 return 0;
6269}
6270
Oliver Endrissebc7de22011-07-03 13:49:44 -03006271static int drxk_read_signal_strength(struct dvb_frontend *fe,
6272 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006273{
6274 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006275 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006276
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006277 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006278 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006279 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006280 return 0;
6281}
6282
6283static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6284{
6285 struct drxk_state *state = fe->demodulator_priv;
6286 s32 snr2;
6287
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006288 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006289 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006290 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006291 return 0;
6292}
6293
6294static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6295{
6296 struct drxk_state *state = fe->demodulator_priv;
6297 u16 err;
6298
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006299 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006300 DVBTQAMGetAccPktErr(state, &err);
6301 *ucblocks = (u32) err;
6302 return 0;
6303}
6304
Oliver Endrissebc7de22011-07-03 13:49:44 -03006305static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6306 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006307{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006308 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006309 sets->min_delay_ms = 3000;
6310 sets->max_drift = 0;
6311 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006312 return 0;
6313}
6314
Oliver Endrissebc7de22011-07-03 13:49:44 -03006315static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006316{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006317#if 0
6318 struct drxk_state *state = fe->demodulator_priv;
6319
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006320 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006321 kfree(state);
6322#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006323}
6324
Oliver Endrissebc7de22011-07-03 13:49:44 -03006325static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006326{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006327 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006328
6329 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006330 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006331 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006332 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006333 return 0;
6334}
6335
Oliver Endrissebc7de22011-07-03 13:49:44 -03006336static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006337{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006338 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006339
6340 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006341 mutex_unlock(&state->ctlock);
6342 return 0;
6343}
6344
Oliver Endrissebc7de22011-07-03 13:49:44 -03006345static int drxk_t_get_frontend(struct dvb_frontend *fe,
6346 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006347{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006348 dprintk(1, "\n");
6349
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006350 return 0;
6351}
6352
6353static struct dvb_frontend_ops drxk_c_ops = {
6354 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006355 .name = "DRXK DVB-C",
6356 .type = FE_QAM,
6357 .frequency_stepsize = 62500,
6358 .frequency_min = 47000000,
6359 .frequency_max = 862000000,
6360 .symbol_rate_min = 870000,
6361 .symbol_rate_max = 11700000,
6362 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6363 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006364 .release = drxk_c_release,
6365 .init = drxk_c_init,
6366 .sleep = drxk_c_sleep,
6367 .i2c_gate_ctrl = drxk_gate_ctrl,
6368
6369 .set_frontend = drxk_set_parameters,
6370 .get_frontend = drxk_c_get_frontend,
6371 .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 = {
6381 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006382 .name = "DRXK DVB-T",
6383 .type = FE_OFDM,
6384 .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
6401 .set_frontend = drxk_set_parameters,
6402 .get_frontend = drxk_t_get_frontend,
6403
6404 .read_status = drxk_read_status,
6405 .read_ber = drxk_read_ber,
6406 .read_signal_strength = drxk_read_signal_strength,
6407 .read_snr = drxk_read_snr,
6408 .read_ucblocks = drxk_read_ucblocks,
6409};
6410
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006411struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6412 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006413 struct dvb_frontend **fe_t)
6414{
6415 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006416 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006417
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006418 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006419 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006420 if (!state)
6421 return NULL;
6422
Oliver Endrissebc7de22011-07-03 13:49:44 -03006423 state->i2c = i2c;
6424 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006425 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006426 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006427 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006428 state->antenna_gpio = config->antenna_gpio;
6429 state->antenna_dvbt = config->antenna_dvbt;
6430
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
6455#ifdef CONFIG_MEDIA_ATTACH
6456 /*
6457 * HACK: As this function initializes both DVB-T and DVB-C fe symbols,
6458 * and calling it twice would create the state twice, leading into
6459 * memory leaks, the right way is to call it only once. However, dvb
6460 * release functions will call symbol_put twice. So, the solution is to
6461 * artificially increment the usage count, in order to allow the
6462 * driver to be released.
6463 */
6464 symbol_get(drxk_attach);
6465#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006466 return &state->c_frontend;
6467
6468error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006469 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006470 kfree(state);
6471 return NULL;
6472}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006473EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006474
6475MODULE_DESCRIPTION("DRX-K driver");
6476MODULE_AUTHOR("Ralph Metzler");
6477MODULE_LICENSE("GPL");