blob: 91f3296917fa60d2a2674a39c50e8f6e73da9bf0 [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);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300859 state->m_GPIO = (ulGPIO == 0 ? 0 : 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300860
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300861 state->m_bPowerDown = false;
862 state->m_currentPowerMode = DRX_POWER_DOWN;
863
864 state->m_enableParallel = (ulSerialMode == 0);
865
866 state->m_rfmirror = (ulRfMirror == 0);
867 state->m_IfAgcPol = false;
868 return 0;
869}
870
871static int DRXX_Open(struct drxk_state *state)
872{
873 int status = 0;
874 u32 jtag = 0;
875 u16 bid = 0;
876 u16 key = 0;
877
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300878 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300879 /* stop lock indicator process */
880 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
881 if (status < 0)
882 goto error;
883 /* Check device id */
884 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
885 if (status < 0)
886 goto error;
887 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
888 if (status < 0)
889 goto error;
890 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
891 if (status < 0)
892 goto error;
893 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
894 if (status < 0)
895 goto error;
896 status = write16(state, SIO_TOP_COMM_KEY__A, key);
897error:
898 if (status < 0)
899 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300900 return status;
901}
902
903static int GetDeviceCapabilities(struct drxk_state *state)
904{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300905 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300906 u32 sioTopJtagidLo = 0;
907 int status;
908
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;
957 break;
958 case 2:
959 state->m_deviceSpin = DRXK_SPIN_A2;
960 break;
961 case 3:
962 state->m_deviceSpin = DRXK_SPIN_A3;
963 break;
964 default:
965 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
966 status = -EINVAL;
967 printk(KERN_ERR "drxk: Spin unknown\n");
968 goto error2;
969 }
970 switch ((sioTopJtagidLo >> 12) & 0xFF) {
971 case 0x13:
972 /* typeId = DRX3913K_TYPE_ID */
973 state->m_hasLNA = false;
974 state->m_hasOOB = false;
975 state->m_hasATV = false;
976 state->m_hasAudio = false;
977 state->m_hasDVBT = true;
978 state->m_hasDVBC = true;
979 state->m_hasSAWSW = true;
980 state->m_hasGPIO2 = false;
981 state->m_hasGPIO1 = false;
982 state->m_hasIRQN = false;
983 break;
984 case 0x15:
985 /* typeId = DRX3915K_TYPE_ID */
986 state->m_hasLNA = false;
987 state->m_hasOOB = false;
988 state->m_hasATV = true;
989 state->m_hasAudio = false;
990 state->m_hasDVBT = true;
991 state->m_hasDVBC = false;
992 state->m_hasSAWSW = true;
993 state->m_hasGPIO2 = true;
994 state->m_hasGPIO1 = true;
995 state->m_hasIRQN = false;
996 break;
997 case 0x16:
998 /* typeId = DRX3916K_TYPE_ID */
999 state->m_hasLNA = false;
1000 state->m_hasOOB = false;
1001 state->m_hasATV = true;
1002 state->m_hasAudio = false;
1003 state->m_hasDVBT = true;
1004 state->m_hasDVBC = false;
1005 state->m_hasSAWSW = true;
1006 state->m_hasGPIO2 = true;
1007 state->m_hasGPIO1 = true;
1008 state->m_hasIRQN = false;
1009 break;
1010 case 0x18:
1011 /* typeId = DRX3918K_TYPE_ID */
1012 state->m_hasLNA = false;
1013 state->m_hasOOB = false;
1014 state->m_hasATV = true;
1015 state->m_hasAudio = true;
1016 state->m_hasDVBT = true;
1017 state->m_hasDVBC = false;
1018 state->m_hasSAWSW = true;
1019 state->m_hasGPIO2 = true;
1020 state->m_hasGPIO1 = true;
1021 state->m_hasIRQN = false;
1022 break;
1023 case 0x21:
1024 /* typeId = DRX3921K_TYPE_ID */
1025 state->m_hasLNA = false;
1026 state->m_hasOOB = false;
1027 state->m_hasATV = true;
1028 state->m_hasAudio = true;
1029 state->m_hasDVBT = true;
1030 state->m_hasDVBC = true;
1031 state->m_hasSAWSW = true;
1032 state->m_hasGPIO2 = true;
1033 state->m_hasGPIO1 = true;
1034 state->m_hasIRQN = false;
1035 break;
1036 case 0x23:
1037 /* typeId = DRX3923K_TYPE_ID */
1038 state->m_hasLNA = false;
1039 state->m_hasOOB = false;
1040 state->m_hasATV = true;
1041 state->m_hasAudio = true;
1042 state->m_hasDVBT = true;
1043 state->m_hasDVBC = true;
1044 state->m_hasSAWSW = true;
1045 state->m_hasGPIO2 = true;
1046 state->m_hasGPIO1 = true;
1047 state->m_hasIRQN = false;
1048 break;
1049 case 0x25:
1050 /* typeId = DRX3925K_TYPE_ID */
1051 state->m_hasLNA = false;
1052 state->m_hasOOB = false;
1053 state->m_hasATV = true;
1054 state->m_hasAudio = true;
1055 state->m_hasDVBT = true;
1056 state->m_hasDVBC = true;
1057 state->m_hasSAWSW = true;
1058 state->m_hasGPIO2 = true;
1059 state->m_hasGPIO1 = true;
1060 state->m_hasIRQN = false;
1061 break;
1062 case 0x26:
1063 /* typeId = DRX3926K_TYPE_ID */
1064 state->m_hasLNA = false;
1065 state->m_hasOOB = false;
1066 state->m_hasATV = true;
1067 state->m_hasAudio = false;
1068 state->m_hasDVBT = true;
1069 state->m_hasDVBC = true;
1070 state->m_hasSAWSW = true;
1071 state->m_hasGPIO2 = true;
1072 state->m_hasGPIO1 = true;
1073 state->m_hasIRQN = false;
1074 break;
1075 default:
1076 printk(KERN_ERR "drxk: DeviceID not supported = %02x\n",
1077 ((sioTopJtagidLo >> 12) & 0xFF));
1078 status = -EINVAL;
1079 goto error2;
1080 }
1081
1082error:
1083 if (status < 0)
1084 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1085
1086error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001087 return status;
1088}
1089
1090static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1091{
1092 int status;
1093 bool powerdown_cmd;
1094
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001095 dprintk(1, "\n");
1096
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001097 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001098 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001099 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001100 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001101 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1102 msleep(1);
1103
1104 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001105 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1106 ((state->m_HICfgCtrl) &
1107 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1108 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001109 if (powerdown_cmd == false) {
1110 /* Wait until command rdy */
1111 u32 retryCount = 0;
1112 u16 waitCmd;
1113
1114 do {
1115 msleep(1);
1116 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001117 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1118 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001119 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1120 && (waitCmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001121 if (status < 0)
1122 goto error;
1123 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001124 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001125error:
1126 if (status < 0)
1127 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1128
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001129 return status;
1130}
1131
1132static int HI_CfgCommand(struct drxk_state *state)
1133{
1134 int status;
1135
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001136 dprintk(1, "\n");
1137
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001138 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001139
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001140 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1141 if (status < 0)
1142 goto error;
1143 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1144 if (status < 0)
1145 goto error;
1146 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1147 if (status < 0)
1148 goto error;
1149 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1150 if (status < 0)
1151 goto error;
1152 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1153 if (status < 0)
1154 goto error;
1155 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1156 if (status < 0)
1157 goto error;
1158 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1159 if (status < 0)
1160 goto error;
1161
1162 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1163error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001164 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001165 if (status < 0)
1166 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001167 return status;
1168}
1169
1170static int InitHI(struct drxk_state *state)
1171{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001172 dprintk(1, "\n");
1173
Oliver Endrissebc7de22011-07-03 13:49:44 -03001174 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001175 state->m_HICfgTimeout = 0x96FF;
1176 /* port/bridge/power down ctrl */
1177 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001178
Oliver Endrissebc7de22011-07-03 13:49:44 -03001179 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001180}
1181
1182static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1183{
1184 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001185 u16 sioPdrMclkCfg = 0;
1186 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001187
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001188 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001189
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001190 /* stop lock indicator process */
1191 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1192 if (status < 0)
1193 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001194
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001195 /* MPEG TS pad configuration */
1196 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1197 if (status < 0)
1198 goto error;
1199
1200 if (mpegEnable == false) {
1201 /* Set MPEG TS pads to inputmode */
1202 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1203 if (status < 0)
1204 goto error;
1205 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1206 if (status < 0)
1207 goto error;
1208 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1209 if (status < 0)
1210 goto error;
1211 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1212 if (status < 0)
1213 goto error;
1214 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1215 if (status < 0)
1216 goto error;
1217 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1218 if (status < 0)
1219 goto error;
1220 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1221 if (status < 0)
1222 goto error;
1223 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1224 if (status < 0)
1225 goto error;
1226 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1227 if (status < 0)
1228 goto error;
1229 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1230 if (status < 0)
1231 goto error;
1232 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1233 if (status < 0)
1234 goto error;
1235 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1236 if (status < 0)
1237 goto error;
1238 } else {
1239 /* Enable MPEG output */
1240 sioPdrMdxCfg =
1241 ((state->m_TSDataStrength <<
1242 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1243 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1244 SIO_PDR_MCLK_CFG_DRIVE__B) |
1245 0x0003);
1246
1247 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1248 if (status < 0)
1249 goto error;
1250 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
1251 if (status < 0)
1252 goto error;
1253 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
1254 if (status < 0)
1255 goto error;
1256 if (state->m_enableParallel == true) {
1257 /* paralel -> enable MD1 to MD7 */
1258 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001259 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001260 goto error;
1261 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001262 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001263 goto error;
1264 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001265 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001266 goto error;
1267 status = write16(state, SIO_PDR_MD4_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_MD5_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_MD6_CFG__A, sioPdrMdxCfg);
1274 if (status < 0)
1275 goto error;
1276 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1277 if (status < 0)
1278 goto error;
1279 } else {
1280 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1281 SIO_PDR_MD0_CFG_DRIVE__B)
1282 | 0x0003);
1283 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001284 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001285 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001286 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001287 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001288 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001289 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001290 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001291 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001292 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001293 status = write16(state, SIO_PDR_MD4_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_MD5_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_MD6_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_MD7_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;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001305 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001306 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001307 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001308 goto error;
1309 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001310 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001311 goto error;
1312 }
1313 /* Enable MB output over MPEG pads and ctl input */
1314 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1315 if (status < 0)
1316 goto error;
1317 /* Write nomagic word to enable pdr reg write */
1318 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1319error:
1320 if (status < 0)
1321 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001322 return status;
1323}
1324
1325static int MPEGTSDisable(struct drxk_state *state)
1326{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001327 dprintk(1, "\n");
1328
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001329 return MPEGTSConfigurePins(state, false);
1330}
1331
1332static int BLChainCmd(struct drxk_state *state,
1333 u16 romOffset, u16 nrOfElements, u32 timeOut)
1334{
1335 u16 blStatus = 0;
1336 int status;
1337 unsigned long end;
1338
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001339 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001340 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001341 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1342 if (status < 0)
1343 goto error;
1344 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1345 if (status < 0)
1346 goto error;
1347 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1348 if (status < 0)
1349 goto error;
1350 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1351 if (status < 0)
1352 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001353
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001354 end = jiffies + msecs_to_jiffies(timeOut);
1355 do {
1356 msleep(1);
1357 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1358 if (status < 0)
1359 goto error;
1360 } while ((blStatus == 0x1) &&
1361 ((time_is_after_jiffies(end))));
1362
1363 if (blStatus == 0x1) {
1364 printk(KERN_ERR "drxk: SIO not ready\n");
1365 status = -EINVAL;
1366 goto error2;
1367 }
1368error:
1369 if (status < 0)
1370 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1371error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001372 mutex_unlock(&state->mutex);
1373 return status;
1374}
1375
1376
1377static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001378 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001379{
1380 const u8 *pSrc = pMCImage;
1381 u16 Flags;
1382 u16 Drain;
1383 u32 Address;
1384 u16 nBlocks;
1385 u16 BlockSize;
1386 u16 BlockCRC;
1387 u32 offset = 0;
1388 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001389 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001390
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001391 dprintk(1, "\n");
1392
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001393 /* down the drain (we don care about MAGIC_WORD) */
1394 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001395 pSrc += sizeof(u16);
1396 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001397 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001398 pSrc += sizeof(u16);
1399 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001400
1401 for (i = 0; i < nBlocks; i += 1) {
1402 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001403 (pSrc[2] << 8) | pSrc[3];
1404 pSrc += sizeof(u32);
1405 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001406
1407 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001408 pSrc += sizeof(u16);
1409 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001410
1411 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001412 pSrc += sizeof(u16);
1413 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001414
1415 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001416 pSrc += sizeof(u16);
1417 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001418
1419 if (offset + BlockSize > Length) {
1420 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1421 return -EINVAL;
1422 }
1423
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001424 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001425 if (status < 0) {
1426 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001427 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001428 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001429 pSrc += BlockSize;
1430 offset += BlockSize;
1431 }
1432 return status;
1433}
1434
1435static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1436{
1437 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001438 u16 data = 0;
1439 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001440 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1441 unsigned long end;
1442
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001443 dprintk(1, "\n");
1444
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001445 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001446 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001447 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1448 }
1449
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001450 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1451 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001452 /* tokenring already has correct status */
1453 return status;
1454 }
1455 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001456 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001457
Oliver Endrissebc7de22011-07-03 13:49:44 -03001458 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001459 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001460 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001461 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001462 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001463 msleep(1);
1464 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001465 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001466 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001467 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001468 }
1469 return status;
1470}
1471
1472static int MPEGTSStop(struct drxk_state *state)
1473{
1474 int status = 0;
1475 u16 fecOcSncMode = 0;
1476 u16 fecOcIprMode = 0;
1477
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001478 dprintk(1, "\n");
1479
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001480 /* Gracefull shutdown (byte boundaries) */
1481 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1482 if (status < 0)
1483 goto error;
1484 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1485 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1486 if (status < 0)
1487 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001488
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001489 /* Suppress MCLK during absence of data */
1490 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1491 if (status < 0)
1492 goto error;
1493 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1494 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1495
1496error:
1497 if (status < 0)
1498 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1499
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001500 return status;
1501}
1502
1503static int scu_command(struct drxk_state *state,
1504 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001505 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001506{
1507#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1508#error DRXK register mapping no longer compatible with this routine!
1509#endif
1510 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001511 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001512 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001513 u8 buffer[34];
1514 int cnt = 0, ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001515
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001516 dprintk(1, "\n");
1517
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001518 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1519 ((resultLen > 0) && (result == NULL)))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001520 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001521
1522 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001523
1524 /* assume that the command register is ready
1525 since it is checked afterwards */
1526 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1527 buffer[cnt++] = (parameter[ii] & 0xFF);
1528 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1529 }
1530 buffer[cnt++] = (cmd & 0xFF);
1531 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1532
1533 write_block(state, SCU_RAM_PARAM_0__A -
1534 (parameterLen - 1), cnt, buffer);
1535 /* Wait until SCU has processed command */
1536 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001537 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001538 msleep(1);
1539 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1540 if (status < 0)
1541 goto error;
1542 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1543 if (curCmd != DRX_SCU_READY) {
1544 printk(KERN_ERR "drxk: SCU not ready\n");
1545 status = -EIO;
1546 goto error2;
1547 }
1548 /* read results */
1549 if ((resultLen > 0) && (result != NULL)) {
1550 s16 err;
1551 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001552
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001553 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1554 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001555 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001556 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001557 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001558
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001559 /* Check if an error was reported by SCU */
1560 err = (s16)result[0];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001561
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001562 /* check a few fixed error codes */
1563 if (err == SCU_RESULT_UNKSTD) {
1564 printk(KERN_ERR "drxk: SCU_RESULT_UNKSTD\n");
1565 status = -EINVAL;
1566 goto error2;
1567 } else if (err == SCU_RESULT_UNKCMD) {
1568 printk(KERN_ERR "drxk: SCU_RESULT_UNKCMD\n");
1569 status = -EINVAL;
1570 goto error2;
1571 } else if (err < 0) {
1572 /*
1573 * here it is assumed that a nagative result means
1574 * error, and positive no error
1575 */
1576 printk(KERN_ERR "drxk: %s ERROR: %d\n", __func__, err);
1577 status = -EINVAL;
1578 goto error2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001579 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001580 }
1581
1582error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001583 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001584 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001585
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001586error2:
1587 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001588 return status;
1589}
1590
1591static int SetIqmAf(struct drxk_state *state, bool active)
1592{
1593 u16 data = 0;
1594 int status;
1595
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001596 dprintk(1, "\n");
1597
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001598 /* Configure IQM */
1599 status = read16(state, IQM_AF_STDBY__A, &data);
1600 if (status < 0)
1601 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001602
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001603 if (!active) {
1604 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1605 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1606 | IQM_AF_STDBY_STDBY_PD_STANDBY
1607 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1608 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1609 } else {
1610 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1611 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1612 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1613 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1614 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1615 );
1616 }
1617 status = write16(state, IQM_AF_STDBY__A, data);
1618
1619error:
1620 if (status < 0)
1621 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001622 return status;
1623}
1624
Oliver Endrissebc7de22011-07-03 13:49:44 -03001625static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001626{
1627 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001628 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001629
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001630 dprintk(1, "\n");
1631
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001632 /* Check arguments */
1633 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001634 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001635
1636 switch (*mode) {
1637 case DRX_POWER_UP:
1638 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1639 break;
1640 case DRXK_POWER_DOWN_OFDM:
1641 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1642 break;
1643 case DRXK_POWER_DOWN_CORE:
1644 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1645 break;
1646 case DRXK_POWER_DOWN_PLL:
1647 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1648 break;
1649 case DRX_POWER_DOWN:
1650 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1651 break;
1652 default:
1653 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001654 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001655 break;
1656 }
1657
1658 /* If already in requested power mode, do nothing */
1659 if (state->m_currentPowerMode == *mode)
1660 return 0;
1661
1662 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001663 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001664 status = PowerUpDevice(state);
1665 if (status < 0)
1666 goto error;
1667 status = DVBTEnableOFDMTokenRing(state, true);
1668 if (status < 0)
1669 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001670 }
1671
1672 if (*mode == DRX_POWER_UP) {
1673 /* Restore analog & pin configuartion */
1674 } else {
1675 /* Power down to requested mode */
1676 /* Backup some register settings */
1677 /* Set pins with possible pull-ups connected
1678 to them in input mode */
1679 /* Analog power down */
1680 /* ADC power down */
1681 /* Power down device */
1682 /* stop all comm_exec */
1683 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001684 switch (state->m_OperationMode) {
1685 case OM_DVBT:
1686 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001687 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001688 goto error;
1689 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001690 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001691 goto error;
1692 break;
1693 case OM_QAM_ITU_A:
1694 case OM_QAM_ITU_C:
1695 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001696 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001697 goto error;
1698 status = PowerDownQAM(state);
1699 if (status < 0)
1700 goto error;
1701 break;
1702 default:
1703 break;
1704 }
1705 status = DVBTEnableOFDMTokenRing(state, false);
1706 if (status < 0)
1707 goto error;
1708 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1709 if (status < 0)
1710 goto error;
1711 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1712 if (status < 0)
1713 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001714
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001715 if (*mode != DRXK_POWER_DOWN_OFDM) {
1716 state->m_HICfgCtrl |=
1717 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1718 status = HI_CfgCommand(state);
1719 if (status < 0)
1720 goto error;
1721 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001722 }
1723 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001724
1725error:
1726 if (status < 0)
1727 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1728
Oliver Endrissebc7de22011-07-03 13:49:44 -03001729 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001730}
1731
1732static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1733{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001734 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001735 u16 cmdResult = 0;
1736 u16 data = 0;
1737 int status;
1738
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001739 dprintk(1, "\n");
1740
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001741 status = read16(state, SCU_COMM_EXEC__A, &data);
1742 if (status < 0)
1743 goto error;
1744 if (data == SCU_COMM_EXEC_ACTIVE) {
1745 /* Send OFDM stop command */
1746 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 -03001747 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001748 goto error;
1749 /* Send OFDM reset command */
1750 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1751 if (status < 0)
1752 goto error;
1753 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001754
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001755 /* Reset datapath for OFDM, processors first */
1756 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1757 if (status < 0)
1758 goto error;
1759 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1760 if (status < 0)
1761 goto error;
1762 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1763 if (status < 0)
1764 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001765
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001766 /* powerdown AFE */
1767 status = SetIqmAf(state, false);
1768 if (status < 0)
1769 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001770
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001771 /* powerdown to OFDM mode */
1772 if (setPowerMode) {
1773 status = CtrlPowerMode(state, &powerMode);
1774 if (status < 0)
1775 goto error;
1776 }
1777error:
1778 if (status < 0)
1779 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001780 return status;
1781}
1782
Oliver Endrissebc7de22011-07-03 13:49:44 -03001783static int SetOperationMode(struct drxk_state *state,
1784 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001785{
1786 int status = 0;
1787
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001788 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001789 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001790 Stop and power down previous standard
1791 TODO investigate total power down instead of partial
1792 power down depending on "previous" standard.
1793 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001794
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001795 /* disable HW lock indicator */
1796 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1797 if (status < 0)
1798 goto error;
1799
1800 if (state->m_OperationMode != oMode) {
1801 switch (state->m_OperationMode) {
1802 /* OM_NONE was added for start up */
1803 case OM_NONE:
1804 break;
1805 case OM_DVBT:
1806 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001807 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001808 goto error;
1809 status = PowerDownDVBT(state, true);
1810 if (status < 0)
1811 goto error;
1812 state->m_OperationMode = OM_NONE;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001813 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001814 case OM_QAM_ITU_A: /* fallthrough */
1815 case OM_QAM_ITU_C:
1816 status = MPEGTSStop(state);
1817 if (status < 0)
1818 goto error;
1819 status = PowerDownQAM(state);
1820 if (status < 0)
1821 goto error;
1822 state->m_OperationMode = OM_NONE;
1823 break;
1824 case OM_QAM_ITU_B:
1825 default:
1826 status = -EINVAL;
1827 goto error;
1828 }
1829
1830 /*
1831 Power up new standard
1832 */
1833 switch (oMode) {
1834 case OM_DVBT:
Mauro Carvalho Chehabd6a05402011-07-10 13:07:36 -03001835 state->m_OperationMode = oMode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001836 status = SetDVBTStandard(state, oMode);
1837 if (status < 0)
1838 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001839 break;
1840 case OM_QAM_ITU_A: /* fallthrough */
1841 case OM_QAM_ITU_C:
Mauro Carvalho Chehabd6a05402011-07-10 13:07:36 -03001842 state->m_OperationMode = oMode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001843 status = SetQAMStandard(state, oMode);
1844 if (status < 0)
1845 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001846 break;
1847 case OM_QAM_ITU_B:
1848 default:
1849 status = -EINVAL;
1850 }
1851 }
1852error:
1853 if (status < 0)
1854 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1855 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001856}
1857
1858static int Start(struct drxk_state *state, s32 offsetFreq,
1859 s32 IntermediateFrequency)
1860{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001861 int status = -EINVAL;
1862
1863 u16 IFreqkHz;
1864 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001865
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001866 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001867 if (state->m_DrxkState != DRXK_STOPPED &&
1868 state->m_DrxkState != DRXK_DTV_STARTED)
1869 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001870
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001871 state->m_bMirrorFreqSpect = (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001872
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001873 if (IntermediateFrequency < 0) {
1874 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1875 IntermediateFrequency = -IntermediateFrequency;
1876 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001877
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001878 switch (state->m_OperationMode) {
1879 case OM_QAM_ITU_A:
1880 case OM_QAM_ITU_C:
1881 IFreqkHz = (IntermediateFrequency / 1000);
1882 status = SetQAM(state, IFreqkHz, OffsetkHz);
1883 if (status < 0)
1884 goto error;
1885 state->m_DrxkState = DRXK_DTV_STARTED;
1886 break;
1887 case OM_DVBT:
1888 IFreqkHz = (IntermediateFrequency / 1000);
1889 status = MPEGTSStop(state);
1890 if (status < 0)
1891 goto error;
1892 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1893 if (status < 0)
1894 goto error;
1895 status = DVBTStart(state);
1896 if (status < 0)
1897 goto error;
1898 state->m_DrxkState = DRXK_DTV_STARTED;
1899 break;
1900 default:
1901 break;
1902 }
1903error:
1904 if (status < 0)
1905 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001906 return status;
1907}
1908
1909static int ShutDown(struct drxk_state *state)
1910{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001911 dprintk(1, "\n");
1912
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001913 MPEGTSStop(state);
1914 return 0;
1915}
1916
Oliver Endrissebc7de22011-07-03 13:49:44 -03001917static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1918 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001919{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001920 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001921
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001922 dprintk(1, "\n");
1923
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001924 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001925 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001926
1927 *pLockStatus = NOT_LOCKED;
1928
1929 /* define the SCU command code */
1930 switch (state->m_OperationMode) {
1931 case OM_QAM_ITU_A:
1932 case OM_QAM_ITU_B:
1933 case OM_QAM_ITU_C:
1934 status = GetQAMLockStatus(state, pLockStatus);
1935 break;
1936 case OM_DVBT:
1937 status = GetDVBTLockStatus(state, pLockStatus);
1938 break;
1939 default:
1940 break;
1941 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001942error:
1943 if (status < 0)
1944 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001945 return status;
1946}
1947
1948static int MPEGTSStart(struct drxk_state *state)
1949{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001950 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001951
1952 u16 fecOcSncMode = 0;
1953
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001954 /* Allow OC to sync again */
1955 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1956 if (status < 0)
1957 goto error;
1958 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1959 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1960 if (status < 0)
1961 goto error;
1962 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1963error:
1964 if (status < 0)
1965 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001966 return status;
1967}
1968
1969static int MPEGTSDtoInit(struct drxk_state *state)
1970{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001971 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001972
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001973 dprintk(1, "\n");
1974
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001975 /* Rate integration settings */
1976 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1977 if (status < 0)
1978 goto error;
1979 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1980 if (status < 0)
1981 goto error;
1982 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1983 if (status < 0)
1984 goto error;
1985 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1986 if (status < 0)
1987 goto error;
1988 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
1989 if (status < 0)
1990 goto error;
1991 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
1992 if (status < 0)
1993 goto error;
1994 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
1995 if (status < 0)
1996 goto error;
1997 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
1998 if (status < 0)
1999 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002000
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002001 /* Additional configuration */
2002 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2003 if (status < 0)
2004 goto error;
2005 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2006 if (status < 0)
2007 goto error;
2008 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2009error:
2010 if (status < 0)
2011 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2012
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002013 return status;
2014}
2015
Oliver Endrissebc7de22011-07-03 13:49:44 -03002016static int MPEGTSDtoSetup(struct drxk_state *state,
2017 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002018{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002019 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002020
Oliver Endrissebc7de22011-07-03 13:49:44 -03002021 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2022 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2023 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2024 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2025 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2026 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2027 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002028 u16 fecOcTmdMode = 0;
2029 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002030 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002031 bool staticCLK = false;
2032
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002033 dprintk(1, "\n");
2034
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002035 /* Check insertion of the Reed-Solomon parity bytes */
2036 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2037 if (status < 0)
2038 goto error;
2039 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2040 if (status < 0)
2041 goto error;
2042 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2043 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2044 if (state->m_insertRSByte == true) {
2045 /* enable parity symbol forward */
2046 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2047 /* MVAL disable during parity bytes */
2048 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2049 /* TS burst length to 204 */
2050 fecOcDtoBurstLen = 204;
2051 }
2052
2053 /* Check serial or parrallel output */
2054 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2055 if (state->m_enableParallel == false) {
2056 /* MPEG data output is serial -> set ipr_mode[0] */
2057 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2058 }
2059
2060 switch (oMode) {
2061 case OM_DVBT:
2062 maxBitRate = state->m_DVBTBitrate;
2063 fecOcTmdMode = 3;
2064 fecOcRcnCtlRate = 0xC00000;
2065 staticCLK = state->m_DVBTStaticCLK;
2066 break;
2067 case OM_QAM_ITU_A: /* fallthrough */
2068 case OM_QAM_ITU_C:
2069 fecOcTmdMode = 0x0004;
2070 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2071 maxBitRate = state->m_DVBCBitrate;
2072 staticCLK = state->m_DVBCStaticCLK;
2073 break;
2074 default:
2075 status = -EINVAL;
2076 } /* switch (standard) */
2077 if (status < 0)
2078 goto error;
2079
2080 /* Configure DTO's */
2081 if (staticCLK) {
2082 u32 bitRate = 0;
2083
2084 /* Rational DTO for MCLK source (static MCLK rate),
2085 Dynamic DTO for optimal grouping
2086 (avoid intra-packet gaps),
2087 DTO offset enable to sync TS burst with MSTRT */
2088 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2089 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2090 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2091 FEC_OC_FCT_MODE_VIRT_ENA__M);
2092
2093 /* Check user defined bitrate */
2094 bitRate = maxBitRate;
2095 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2096 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002097 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002098 /* Rational DTO period:
2099 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002100
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002101 Result should be floored,
2102 to make sure >= requested bitrate
2103 */
2104 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2105 * 1000) / bitRate);
2106 if (fecOcDtoPeriod <= 2)
2107 fecOcDtoPeriod = 0;
2108 else
2109 fecOcDtoPeriod -= 2;
2110 fecOcTmdIntUpdRate = 8;
2111 } else {
2112 /* (commonAttr->staticCLK == false) => dynamic mode */
2113 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2114 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2115 fecOcTmdIntUpdRate = 5;
2116 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002117
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002118 /* Write appropriate registers with requested configuration */
2119 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2120 if (status < 0)
2121 goto error;
2122 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2123 if (status < 0)
2124 goto error;
2125 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2126 if (status < 0)
2127 goto error;
2128 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2129 if (status < 0)
2130 goto error;
2131 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2132 if (status < 0)
2133 goto error;
2134 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2135 if (status < 0)
2136 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002137
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002138 /* Rate integration settings */
2139 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2140 if (status < 0)
2141 goto error;
2142 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2143 if (status < 0)
2144 goto error;
2145 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2146error:
2147 if (status < 0)
2148 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002149 return status;
2150}
2151
2152static int MPEGTSConfigurePolarity(struct drxk_state *state)
2153{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002154 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002155
2156 /* Data mask for the output data byte */
2157 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002158 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2159 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2160 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2161 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002162
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002163 dprintk(1, "\n");
2164
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002165 /* Control selective inversion of output bits */
2166 fecOcRegIprInvert &= (~(InvertDataMask));
2167 if (state->m_invertDATA == true)
2168 fecOcRegIprInvert |= InvertDataMask;
2169 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2170 if (state->m_invertERR == true)
2171 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2172 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2173 if (state->m_invertSTR == true)
2174 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2175 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2176 if (state->m_invertVAL == true)
2177 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2178 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2179 if (state->m_invertCLK == true)
2180 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002181
2182 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002183}
2184
2185#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2186
2187static int SetAgcRf(struct drxk_state *state,
2188 struct SCfgAgc *pAgcCfg, bool isDTV)
2189{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002190 int status = -EINVAL;
2191 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002192 struct SCfgAgc *pIfAgcSettings;
2193
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002194 dprintk(1, "\n");
2195
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002196 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002197 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002198
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002199 switch (pAgcCfg->ctrlMode) {
2200 case DRXK_AGC_CTRL_AUTO:
2201 /* Enable RF AGC DAC */
2202 status = read16(state, IQM_AF_STDBY__A, &data);
2203 if (status < 0)
2204 goto error;
2205 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2206 status = write16(state, IQM_AF_STDBY__A, data);
2207 if (status < 0)
2208 goto error;
2209 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2210 if (status < 0)
2211 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002212
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002213 /* Enable SCU RF AGC loop */
2214 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002215
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002216 /* Polarity */
2217 if (state->m_RfAgcPol)
2218 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2219 else
2220 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2221 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2222 if (status < 0)
2223 goto error;
2224
2225 /* Set speed (using complementary reduction value) */
2226 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2227 if (status < 0)
2228 goto error;
2229
2230 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2231 data |= (~(pAgcCfg->speed <<
2232 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2233 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2234
2235 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2236 if (status < 0)
2237 goto error;
2238
2239 if (IsDVBT(state))
2240 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2241 else if (IsQAM(state))
2242 pIfAgcSettings = &state->m_qamIfAgcCfg;
2243 else
2244 pIfAgcSettings = &state->m_atvIfAgcCfg;
2245 if (pIfAgcSettings == NULL) {
2246 status = -EINVAL;
2247 goto error;
2248 }
2249
2250 /* Set TOP, only if IF-AGC is in AUTO mode */
2251 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2252 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002253 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002254 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002255
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002256 /* Cut-Off current */
2257 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2258 if (status < 0)
2259 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002260
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002261 /* Max. output level */
2262 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2263 if (status < 0)
2264 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002265
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002266 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002267
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002268 case DRXK_AGC_CTRL_USER:
2269 /* Enable RF AGC DAC */
2270 status = read16(state, IQM_AF_STDBY__A, &data);
2271 if (status < 0)
2272 goto error;
2273 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2274 status = write16(state, IQM_AF_STDBY__A, data);
2275 if (status < 0)
2276 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002277
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002278 /* Disable SCU RF AGC loop */
2279 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2280 if (status < 0)
2281 goto error;
2282 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2283 if (state->m_RfAgcPol)
2284 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2285 else
2286 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2287 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2288 if (status < 0)
2289 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002290
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002291 /* SCU c.o.c. to 0, enabling full control range */
2292 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2293 if (status < 0)
2294 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002295
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002296 /* Write value to output pin */
2297 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2298 if (status < 0)
2299 goto error;
2300 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002301
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002302 case DRXK_AGC_CTRL_OFF:
2303 /* Disable RF AGC DAC */
2304 status = read16(state, IQM_AF_STDBY__A, &data);
2305 if (status < 0)
2306 goto error;
2307 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2308 status = write16(state, IQM_AF_STDBY__A, data);
2309 if (status < 0)
2310 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002311
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002312 /* Disable SCU RF AGC loop */
2313 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2314 if (status < 0)
2315 goto error;
2316 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2317 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2318 if (status < 0)
2319 goto error;
2320 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002321
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002322 default:
2323 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002324
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002325 }
2326error:
2327 if (status < 0)
2328 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002329 return status;
2330}
2331
2332#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2333
Oliver Endrissebc7de22011-07-03 13:49:44 -03002334static int SetAgcIf(struct drxk_state *state,
2335 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002336{
2337 u16 data = 0;
2338 int status = 0;
2339 struct SCfgAgc *pRfAgcSettings;
2340
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002341 dprintk(1, "\n");
2342
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002343 switch (pAgcCfg->ctrlMode) {
2344 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002345
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002346 /* Enable IF AGC DAC */
2347 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002348 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002349 goto error;
2350 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2351 status = write16(state, IQM_AF_STDBY__A, data);
2352 if (status < 0)
2353 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002354
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002355 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2356 if (status < 0)
2357 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002358
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002359 /* Enable SCU IF AGC loop */
2360 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2361
2362 /* Polarity */
2363 if (state->m_IfAgcPol)
2364 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2365 else
2366 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2367 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2368 if (status < 0)
2369 goto error;
2370
2371 /* Set speed (using complementary reduction value) */
2372 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2373 if (status < 0)
2374 goto error;
2375 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2376 data |= (~(pAgcCfg->speed <<
2377 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2378 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2379
2380 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2381 if (status < 0)
2382 goto error;
2383
2384 if (IsQAM(state))
2385 pRfAgcSettings = &state->m_qamRfAgcCfg;
2386 else
2387 pRfAgcSettings = &state->m_atvRfAgcCfg;
2388 if (pRfAgcSettings == NULL)
2389 return -1;
2390 /* Restore TOP */
2391 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2392 if (status < 0)
2393 goto error;
2394 break;
2395
2396 case DRXK_AGC_CTRL_USER:
2397
2398 /* Enable IF AGC DAC */
2399 status = read16(state, IQM_AF_STDBY__A, &data);
2400 if (status < 0)
2401 goto error;
2402 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2403 status = write16(state, IQM_AF_STDBY__A, data);
2404 if (status < 0)
2405 goto error;
2406
2407 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2408 if (status < 0)
2409 goto error;
2410
2411 /* Disable SCU IF AGC loop */
2412 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2413
2414 /* Polarity */
2415 if (state->m_IfAgcPol)
2416 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2417 else
2418 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2419 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2420 if (status < 0)
2421 goto error;
2422
2423 /* Write value to output pin */
2424 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2425 if (status < 0)
2426 goto error;
2427 break;
2428
2429 case DRXK_AGC_CTRL_OFF:
2430
2431 /* Disable If AGC DAC */
2432 status = read16(state, IQM_AF_STDBY__A, &data);
2433 if (status < 0)
2434 goto error;
2435 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2436 status = write16(state, IQM_AF_STDBY__A, data);
2437 if (status < 0)
2438 goto error;
2439
2440 /* Disable SCU IF AGC loop */
2441 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2442 if (status < 0)
2443 goto error;
2444 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2445 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2446 if (status < 0)
2447 goto error;
2448 break;
2449 } /* switch (agcSettingsIf->ctrlMode) */
2450
2451 /* always set the top to support
2452 configurations without if-loop */
2453 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2454error:
2455 if (status < 0)
2456 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002457 return status;
2458}
2459
2460static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2461{
2462 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002463 int status;
2464 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002465
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002466 dprintk(1, "\n");
2467
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002468 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2469 if (status < 0) {
2470 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2471 return status;
2472 }
2473
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002474 *pValue = 0;
2475
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002476 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2477 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2478 if (Level < 14000)
2479 *pValue = (14000 - Level) / 4;
2480 else
2481 *pValue = 0;
2482
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002483 return status;
2484}
2485
Oliver Endrissebc7de22011-07-03 13:49:44 -03002486static int GetQAMSignalToNoise(struct drxk_state *state,
2487 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002488{
2489 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002490 u16 qamSlErrPower = 0; /* accum. error between
2491 raw and sliced symbols */
2492 u32 qamSlSigPower = 0; /* used for MER, depends of
2493 QAM constellation */
2494 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002495
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002496 dprintk(1, "\n");
2497
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002498 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002499
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002500 /* get the register value needed for MER */
2501 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2502 if (status < 0) {
2503 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2504 return -EINVAL;
2505 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002506
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002507 switch (state->param.u.qam.modulation) {
2508 case QAM_16:
2509 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2510 break;
2511 case QAM_32:
2512 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2513 break;
2514 case QAM_64:
2515 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2516 break;
2517 case QAM_128:
2518 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2519 break;
2520 default:
2521 case QAM_256:
2522 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2523 break;
2524 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002525
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002526 if (qamSlErrPower > 0) {
2527 qamSlMer = Log10Times100(qamSlSigPower) -
2528 Log10Times100((u32) qamSlErrPower);
2529 }
2530 *pSignalToNoise = qamSlMer;
2531
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002532 return status;
2533}
2534
Oliver Endrissebc7de22011-07-03 13:49:44 -03002535static int GetDVBTSignalToNoise(struct drxk_state *state,
2536 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002537{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002538 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002539 u16 regData = 0;
2540 u32 EqRegTdSqrErrI = 0;
2541 u32 EqRegTdSqrErrQ = 0;
2542 u16 EqRegTdSqrErrExp = 0;
2543 u16 EqRegTdTpsPwrOfs = 0;
2544 u16 EqRegTdReqSmbCnt = 0;
2545 u32 tpsCnt = 0;
2546 u32 SqrErrIQ = 0;
2547 u32 a = 0;
2548 u32 b = 0;
2549 u32 c = 0;
2550 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002551 u16 transmissionParams = 0;
2552
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002553 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002554
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002555 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2556 if (status < 0)
2557 goto error;
2558 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2559 if (status < 0)
2560 goto error;
2561 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2562 if (status < 0)
2563 goto error;
2564 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2565 if (status < 0)
2566 goto error;
2567 /* Extend SQR_ERR_I operational range */
2568 EqRegTdSqrErrI = (u32) regData;
2569 if ((EqRegTdSqrErrExp > 11) &&
2570 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2571 EqRegTdSqrErrI += 0x00010000UL;
2572 }
2573 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2574 if (status < 0)
2575 goto error;
2576 /* Extend SQR_ERR_Q operational range */
2577 EqRegTdSqrErrQ = (u32) regData;
2578 if ((EqRegTdSqrErrExp > 11) &&
2579 (EqRegTdSqrErrQ < 0x00000FFFUL))
2580 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002581
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002582 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2583 if (status < 0)
2584 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002585
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002586 /* Check input data for MER */
2587
2588 /* MER calculation (in 0.1 dB) without math.h */
2589 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2590 iMER = 0;
2591 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2592 /* No error at all, this must be the HW reset value
2593 * Apparently no first measurement yet
2594 * Set MER to 0.0 */
2595 iMER = 0;
2596 } else {
2597 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2598 EqRegTdSqrErrExp;
2599 if ((transmissionParams &
2600 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2601 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2602 tpsCnt = 17;
2603 else
2604 tpsCnt = 68;
2605
2606 /* IMER = 100 * log10 (x)
2607 where x = (EqRegTdTpsPwrOfs^2 *
2608 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2609
2610 => IMER = a + b -c
2611 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2612 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2613 c = 100 * log10 (SqrErrIQ)
2614 */
2615
2616 /* log(x) x = 9bits * 9bits->18 bits */
2617 a = Log10Times100(EqRegTdTpsPwrOfs *
2618 EqRegTdTpsPwrOfs);
2619 /* log(x) x = 16bits * 7bits->23 bits */
2620 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2621 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2622 c = Log10Times100(SqrErrIQ);
2623
2624 iMER = a + b;
2625 /* No negative MER, clip to zero */
2626 if (iMER > c)
2627 iMER -= c;
2628 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002629 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002630 }
2631 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002632
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002633error:
2634 if (status < 0)
2635 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002636 return status;
2637}
2638
2639static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2640{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002641 dprintk(1, "\n");
2642
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002643 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002644 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002645 case OM_DVBT:
2646 return GetDVBTSignalToNoise(state, pSignalToNoise);
2647 case OM_QAM_ITU_A:
2648 case OM_QAM_ITU_C:
2649 return GetQAMSignalToNoise(state, pSignalToNoise);
2650 default:
2651 break;
2652 }
2653 return 0;
2654}
2655
2656#if 0
2657static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2658{
2659 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2660 int status = 0;
2661
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002662 dprintk(1, "\n");
2663
Oliver Endrissebc7de22011-07-03 13:49:44 -03002664 static s32 QE_SN[] = {
2665 51, /* QPSK 1/2 */
2666 69, /* QPSK 2/3 */
2667 79, /* QPSK 3/4 */
2668 89, /* QPSK 5/6 */
2669 97, /* QPSK 7/8 */
2670 108, /* 16-QAM 1/2 */
2671 131, /* 16-QAM 2/3 */
2672 146, /* 16-QAM 3/4 */
2673 156, /* 16-QAM 5/6 */
2674 160, /* 16-QAM 7/8 */
2675 165, /* 64-QAM 1/2 */
2676 187, /* 64-QAM 2/3 */
2677 202, /* 64-QAM 3/4 */
2678 216, /* 64-QAM 5/6 */
2679 225, /* 64-QAM 7/8 */
2680 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002681
2682 *pQuality = 0;
2683
2684 do {
2685 s32 SignalToNoise = 0;
2686 u16 Constellation = 0;
2687 u16 CodeRate = 0;
2688 u32 SignalToNoiseRel;
2689 u32 BERQuality;
2690
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002691 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2692 if (status < 0)
2693 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002694 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002695 if (status < 0)
2696 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002697 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2698
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002699 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002700 if (status < 0)
2701 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002702 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2703
2704 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2705 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2706 break;
2707 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002708 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002709 BERQuality = 100;
2710
Oliver Endrissebc7de22011-07-03 13:49:44 -03002711 if (SignalToNoiseRel < -70)
2712 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002713 else if (SignalToNoiseRel < 30)
2714 *pQuality = ((SignalToNoiseRel + 70) *
2715 BERQuality) / 100;
2716 else
2717 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002718 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002719 return 0;
2720};
2721
Oliver Endrissebc7de22011-07-03 13:49:44 -03002722static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002723{
2724 int status = 0;
2725 *pQuality = 0;
2726
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002727 dprintk(1, "\n");
2728
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002729 do {
2730 u32 SignalToNoise = 0;
2731 u32 BERQuality = 100;
2732 u32 SignalToNoiseRel = 0;
2733
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002734 status = GetQAMSignalToNoise(state, &SignalToNoise);
2735 if (status < 0)
2736 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002737
Oliver Endrissebc7de22011-07-03 13:49:44 -03002738 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002739 case QAM_16:
2740 SignalToNoiseRel = SignalToNoise - 200;
2741 break;
2742 case QAM_32:
2743 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002744 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002745 case QAM_64:
2746 SignalToNoiseRel = SignalToNoise - 260;
2747 break;
2748 case QAM_128:
2749 SignalToNoiseRel = SignalToNoise - 290;
2750 break;
2751 default:
2752 case QAM_256:
2753 SignalToNoiseRel = SignalToNoise - 320;
2754 break;
2755 }
2756
2757 if (SignalToNoiseRel < -70)
2758 *pQuality = 0;
2759 else if (SignalToNoiseRel < 30)
2760 *pQuality = ((SignalToNoiseRel + 70) *
2761 BERQuality) / 100;
2762 else
2763 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002764 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002765
2766 return status;
2767}
2768
2769static int GetQuality(struct drxk_state *state, s32 *pQuality)
2770{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002771 dprintk(1, "\n");
2772
Oliver Endrissebc7de22011-07-03 13:49:44 -03002773 switch (state->m_OperationMode) {
2774 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002775 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002776 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002777 return GetDVBCQuality(state, pQuality);
2778 default:
2779 break;
2780 }
2781
2782 return 0;
2783}
2784#endif
2785
2786/* Free data ram in SIO HI */
2787#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2788#define SIO_HI_RA_RAM_USR_END__A 0x420060
2789
2790#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2791#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2792#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2793#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2794
2795#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2796#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2797#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2798
2799static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2800{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002801 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002802
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002803 dprintk(1, "\n");
2804
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002805 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002806 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002807 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002808 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002809
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002810 if (state->no_i2c_bridge)
2811 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002812
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002813 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2814 if (status < 0)
2815 goto error;
2816 if (bEnableBridge) {
2817 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 -03002818 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002819 goto error;
2820 } else {
2821 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2822 if (status < 0)
2823 goto error;
2824 }
2825
2826 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2827
2828error:
2829 if (status < 0)
2830 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002831 return status;
2832}
2833
Oliver Endrissebc7de22011-07-03 13:49:44 -03002834static int SetPreSaw(struct drxk_state *state,
2835 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002836{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002837 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002838
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002839 dprintk(1, "\n");
2840
Oliver Endrissebc7de22011-07-03 13:49:44 -03002841 if ((pPreSawCfg == NULL)
2842 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002843 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002844
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002845 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002846error:
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
2852static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002853 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002854{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002855 u16 blStatus = 0;
2856 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2857 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2858 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002859 unsigned long end;
2860
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002861 dprintk(1, "\n");
2862
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002863 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002864 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2865 if (status < 0)
2866 goto error;
2867 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2868 if (status < 0)
2869 goto error;
2870 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2871 if (status < 0)
2872 goto error;
2873 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2874 if (status < 0)
2875 goto error;
2876 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2877 if (status < 0)
2878 goto error;
2879 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2880 if (status < 0)
2881 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002882
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002883 end = jiffies + msecs_to_jiffies(timeOut);
2884 do {
2885 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2886 if (status < 0)
2887 goto error;
2888 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2889 if (blStatus == 0x1) {
2890 printk(KERN_ERR "drxk: SIO not ready\n");
2891 status = -EINVAL;
2892 goto error2;
2893 }
2894error:
2895 if (status < 0)
2896 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2897error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002898 mutex_unlock(&state->mutex);
2899 return status;
2900
2901}
2902
Oliver Endrissebc7de22011-07-03 13:49:44 -03002903static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002904{
2905 u16 data = 0;
2906 int status;
2907
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002908 dprintk(1, "\n");
2909
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002910 /* Start measurement */
2911 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2912 if (status < 0)
2913 goto error;
2914 status = write16(state, IQM_AF_START_LOCK__A, 1);
2915 if (status < 0)
2916 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002917
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002918 *count = 0;
2919 status = read16(state, IQM_AF_PHASE0__A, &data);
2920 if (status < 0)
2921 goto error;
2922 if (data == 127)
2923 *count = *count + 1;
2924 status = read16(state, IQM_AF_PHASE1__A, &data);
2925 if (status < 0)
2926 goto error;
2927 if (data == 127)
2928 *count = *count + 1;
2929 status = read16(state, IQM_AF_PHASE2__A, &data);
2930 if (status < 0)
2931 goto error;
2932 if (data == 127)
2933 *count = *count + 1;
2934
2935error:
2936 if (status < 0)
2937 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002938 return status;
2939}
2940
2941static int ADCSynchronization(struct drxk_state *state)
2942{
2943 u16 count = 0;
2944 int status;
2945
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002946 dprintk(1, "\n");
2947
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002948 status = ADCSyncMeasurement(state, &count);
2949 if (status < 0)
2950 goto error;
2951
2952 if (count == 1) {
2953 /* Try sampling on a diffrent edge */
2954 u16 clkNeg = 0;
2955
2956 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2957 if (status < 0)
2958 goto error;
2959 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2960 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2961 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2962 clkNeg |=
2963 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2964 } else {
2965 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2966 clkNeg |=
2967 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2968 }
2969 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2970 if (status < 0)
2971 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002972 status = ADCSyncMeasurement(state, &count);
2973 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002974 goto error;
2975 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002976
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002977 if (count < 2)
2978 status = -EINVAL;
2979error:
2980 if (status < 0)
2981 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002982 return status;
2983}
2984
2985static int SetFrequencyShifter(struct drxk_state *state,
2986 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002987 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002988{
2989 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002990 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002991 u32 fmFrequencyShift = 0;
2992 bool tunerMirror = !state->m_bMirrorFreqSpect;
2993 u32 adcFreq;
2994 bool adcFlip;
2995 int status;
2996 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002997 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002998 u32 frequencyShift;
2999 bool imageToSelect;
3000
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003001 dprintk(1, "\n");
3002
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003003 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003004 Program frequency shifter
3005 No need to account for mirroring on RF
3006 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003007 if (isDTV) {
3008 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3009 (state->m_OperationMode == OM_QAM_ITU_C) ||
3010 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003011 selectPosImage = true;
3012 else
3013 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003014 }
3015 if (tunerMirror)
3016 /* tuner doesn't mirror */
3017 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003018 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003019 else
3020 /* tuner mirrors */
3021 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003022 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003023 if (ifFreqActual > samplingFrequency / 2) {
3024 /* adc mirrors */
3025 adcFreq = samplingFrequency - ifFreqActual;
3026 adcFlip = true;
3027 } else {
3028 /* adc doesn't mirror */
3029 adcFreq = ifFreqActual;
3030 adcFlip = false;
3031 }
3032
3033 frequencyShift = adcFreq;
3034 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003035 adcFlip ^ selectPosImage;
3036 state->m_IqmFsRateOfs =
3037 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003038
3039 if (imageToSelect)
3040 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3041
3042 /* Program frequency shifter with tuner offset compensation */
3043 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003044 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3045 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003046 if (status < 0)
3047 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003048 return status;
3049}
3050
3051static int InitAGC(struct drxk_state *state, bool isDTV)
3052{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003053 u16 ingainTgt = 0;
3054 u16 ingainTgtMin = 0;
3055 u16 ingainTgtMax = 0;
3056 u16 clpCyclen = 0;
3057 u16 clpSumMin = 0;
3058 u16 clpDirTo = 0;
3059 u16 snsSumMin = 0;
3060 u16 snsSumMax = 0;
3061 u16 clpSumMax = 0;
3062 u16 snsDirTo = 0;
3063 u16 kiInnergainMin = 0;
3064 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003065 u16 ifIaccuHiTgtMin = 0;
3066 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003067 u16 data = 0;
3068 u16 fastClpCtrlDelay = 0;
3069 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003070 int status = 0;
3071
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003072 dprintk(1, "\n");
3073
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003074 /* Common settings */
3075 snsSumMax = 1023;
3076 ifIaccuHiTgtMin = 2047;
3077 clpCyclen = 500;
3078 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003079
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003080 if (IsQAM(state)) {
3081 /* Standard specific settings */
3082 clpSumMin = 8;
3083 clpDirTo = (u16) -9;
3084 clpCtrlMode = 0;
3085 snsSumMin = 8;
3086 snsDirTo = (u16) -9;
3087 kiInnergainMin = (u16) -1030;
3088 } else {
3089 status = -EINVAL;
3090 goto error;
3091 }
3092 if (IsQAM(state)) {
3093 ifIaccuHiTgtMax = 0x2380;
3094 ifIaccuHiTgt = 0x2380;
3095 ingainTgtMin = 0x0511;
3096 ingainTgt = 0x0511;
3097 ingainTgtMax = 5119;
3098 fastClpCtrlDelay =
3099 state->m_qamIfAgcCfg.FastClipCtrlDelay;
3100 } else {
3101 ifIaccuHiTgtMax = 0x1200;
3102 ifIaccuHiTgt = 0x1200;
3103 ingainTgtMin = 13424;
3104 ingainTgt = 13424;
3105 ingainTgtMax = 30000;
3106 fastClpCtrlDelay =
3107 state->m_dvbtIfAgcCfg.FastClipCtrlDelay;
3108 }
3109 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3110 if (status < 0)
3111 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003112
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003113 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3114 if (status < 0)
3115 goto error;
3116 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3117 if (status < 0)
3118 goto error;
3119 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3120 if (status < 0)
3121 goto error;
3122 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3123 if (status < 0)
3124 goto error;
3125 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3126 if (status < 0)
3127 goto error;
3128 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3129 if (status < 0)
3130 goto error;
3131 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3132 if (status < 0)
3133 goto error;
3134 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3135 if (status < 0)
3136 goto error;
3137 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3138 if (status < 0)
3139 goto error;
3140 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3141 if (status < 0)
3142 goto error;
3143 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3144 if (status < 0)
3145 goto error;
3146 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3147 if (status < 0)
3148 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003149
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003150 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3151 if (status < 0)
3152 goto error;
3153 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3154 if (status < 0)
3155 goto error;
3156 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3157 if (status < 0)
3158 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003159
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003160 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3161 if (status < 0)
3162 goto error;
3163 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3164 if (status < 0)
3165 goto error;
3166 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3167 if (status < 0)
3168 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003169
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003170 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3171 if (status < 0)
3172 goto error;
3173 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3174 if (status < 0)
3175 goto error;
3176 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3177 if (status < 0)
3178 goto error;
3179 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3180 if (status < 0)
3181 goto error;
3182 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3183 if (status < 0)
3184 goto error;
3185 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3186 if (status < 0)
3187 goto error;
3188 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3189 if (status < 0)
3190 goto error;
3191 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3192 if (status < 0)
3193 goto error;
3194 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3195 if (status < 0)
3196 goto error;
3197 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3198 if (status < 0)
3199 goto error;
3200 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3201 if (status < 0)
3202 goto error;
3203 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3204 if (status < 0)
3205 goto error;
3206 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3207 if (status < 0)
3208 goto error;
3209 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3210 if (status < 0)
3211 goto error;
3212 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3213 if (status < 0)
3214 goto error;
3215 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3216 if (status < 0)
3217 goto error;
3218 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3219 if (status < 0)
3220 goto error;
3221 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3222 if (status < 0)
3223 goto error;
3224 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3225 if (status < 0)
3226 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003227
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003228 /* Initialize inner-loop KI gain factors */
3229 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3230 if (status < 0)
3231 goto error;
3232 if (IsQAM(state)) {
3233 data = 0x0657;
3234 data &= ~SCU_RAM_AGC_KI_RF__M;
3235 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3236 data &= ~SCU_RAM_AGC_KI_IF__M;
3237 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3238 }
3239 status = write16(state, SCU_RAM_AGC_KI__A, data);
3240error:
3241 if (status < 0)
3242 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003243 return status;
3244}
3245
Oliver Endrissebc7de22011-07-03 13:49:44 -03003246static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003247{
3248 int status;
3249
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003250 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003251 if (packetErr == NULL)
3252 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3253 else
3254 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3255 if (status < 0)
3256 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003257 return status;
3258}
3259
3260static int DVBTScCommand(struct drxk_state *state,
3261 u16 cmd, u16 subcmd,
3262 u16 param0, u16 param1, u16 param2,
3263 u16 param3, u16 param4)
3264{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003265 u16 curCmd = 0;
3266 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003267 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003268 u16 scExec = 0;
3269 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003270
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003271 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003272 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003273 if (scExec != 1) {
3274 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003275 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003276 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003277 if (status < 0)
3278 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003279
3280 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003281 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003282 do {
3283 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003284 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003285 retryCnt++;
3286 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003287 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3288 goto error;
3289
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003290 /* Write sub-command */
3291 switch (cmd) {
3292 /* All commands using sub-cmd */
3293 case OFDM_SC_RA_RAM_CMD_PROC_START:
3294 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3295 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003296 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3297 if (status < 0)
3298 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003299 break;
3300 default:
3301 /* Do nothing */
3302 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003303 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003304
3305 /* Write needed parameters and the command */
3306 switch (cmd) {
3307 /* All commands using 5 parameters */
3308 /* All commands using 4 parameters */
3309 /* All commands using 3 parameters */
3310 /* All commands using 2 parameters */
3311 case OFDM_SC_RA_RAM_CMD_PROC_START:
3312 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3313 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003314 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003315 /* All commands using 1 parameters */
3316 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3317 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003318 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003319 /* All commands using 0 parameters */
3320 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3321 case OFDM_SC_RA_RAM_CMD_NULL:
3322 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003323 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003324 break;
3325 default:
3326 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003327 status = -EINVAL;
3328 }
3329 if (status < 0)
3330 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003331
3332 /* Wait until sc is ready processing command */
3333 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003334 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003335 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003336 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003337 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003338 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003339 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3340 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003341
3342 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003343 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003344 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003345 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003346 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003347 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003348 if (status < 0)
3349 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003350
3351 /* Retreive results parameters from SC */
3352 switch (cmd) {
3353 /* All commands yielding 5 results */
3354 /* All commands yielding 4 results */
3355 /* All commands yielding 3 results */
3356 /* All commands yielding 2 results */
3357 /* All commands yielding 1 result */
3358 case OFDM_SC_RA_RAM_CMD_USER_IO:
3359 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003360 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003361 /* All commands yielding 0 results */
3362 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3363 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3364 case OFDM_SC_RA_RAM_CMD_PROC_START:
3365 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3366 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3367 case OFDM_SC_RA_RAM_CMD_NULL:
3368 break;
3369 default:
3370 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003371 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003372 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003373 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003374error:
3375 if (status < 0)
3376 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003377 return status;
3378}
3379
Oliver Endrissebc7de22011-07-03 13:49:44 -03003380static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003381{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003382 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003383 int status;
3384
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003385 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003386 status = CtrlPowerMode(state, &powerMode);
3387 if (status < 0)
3388 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003389 return status;
3390}
3391
Oliver Endrissebc7de22011-07-03 13:49:44 -03003392static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003393{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003394 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003395
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003396 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003397 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003398 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003399 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003400 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003401 if (status < 0)
3402 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003403 return status;
3404}
3405
3406#define DEFAULT_FR_THRES_8K 4000
3407static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3408{
3409
3410 int status;
3411
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003412 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003413 if (*enabled == true) {
3414 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003415 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003416 DEFAULT_FR_THRES_8K);
3417 } else {
3418 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003419 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003420 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003421 if (status < 0)
3422 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003423
3424 return status;
3425}
3426
3427static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3428 struct DRXKCfgDvbtEchoThres_t *echoThres)
3429{
3430 u16 data = 0;
3431 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003432
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003433 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003434 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3435 if (status < 0)
3436 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003437
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003438 switch (echoThres->fftMode) {
3439 case DRX_FFTMODE_2K:
3440 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3441 data |= ((echoThres->threshold <<
3442 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3443 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3444 goto error;
3445 case DRX_FFTMODE_8K:
3446 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3447 data |= ((echoThres->threshold <<
3448 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3449 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3450 goto error;
3451 default:
3452 return -EINVAL;
3453 goto error;
3454 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003455
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003456 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3457error:
3458 if (status < 0)
3459 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003460 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003461}
3462
3463static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003464 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003465{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003466 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003467
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003468 dprintk(1, "\n");
3469
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003470 switch (*speed) {
3471 case DRXK_DVBT_SQI_SPEED_FAST:
3472 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3473 case DRXK_DVBT_SQI_SPEED_SLOW:
3474 break;
3475 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003476 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003477 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003478 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003479 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003480error:
3481 if (status < 0)
3482 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003483 return status;
3484}
3485
3486/*============================================================================*/
3487
3488/**
3489* \brief Activate DVBT specific presets
3490* \param demod instance of demodulator.
3491* \return DRXStatus_t.
3492*
3493* Called in DVBTSetStandard
3494*
3495*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003496static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003497{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003498 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003499 bool setincenable = false;
3500 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003501
Oliver Endrissebc7de22011-07-03 13:49:44 -03003502 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3503 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003504
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003505 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003506 status = DVBTCtrlSetIncEnable(state, &setincenable);
3507 if (status < 0)
3508 goto error;
3509 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3510 if (status < 0)
3511 goto error;
3512 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3513 if (status < 0)
3514 goto error;
3515 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3516 if (status < 0)
3517 goto error;
3518 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3519error:
3520 if (status < 0)
3521 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003522 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003523}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003524
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003525/*============================================================================*/
3526
3527/**
3528* \brief Initialize channelswitch-independent settings for DVBT.
3529* \param demod instance of demodulator.
3530* \return DRXStatus_t.
3531*
3532* For ROM code channel filter taps are loaded from the bootloader. For microcode
3533* the DVB-T taps from the drxk_filters.h are used.
3534*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003535static int SetDVBTStandard(struct drxk_state *state,
3536 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003537{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003538 u16 cmdResult = 0;
3539 u16 data = 0;
3540 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003541
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003542 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003543
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003544 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003545 /* added antenna switch */
3546 SwitchAntennaToDVBT(state);
3547 /* send OFDM reset command */
3548 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 -03003549 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003550 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003551
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003552 /* send OFDM setenv command */
3553 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3554 if (status < 0)
3555 goto error;
3556
3557 /* reset datapath for OFDM, processors first */
3558 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3559 if (status < 0)
3560 goto error;
3561 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3562 if (status < 0)
3563 goto error;
3564 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3565 if (status < 0)
3566 goto error;
3567
3568 /* IQM setup */
3569 /* synchronize on ofdstate->m_festart */
3570 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3571 if (status < 0)
3572 goto error;
3573 /* window size for clipping ADC detection */
3574 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3575 if (status < 0)
3576 goto error;
3577 /* window size for for sense pre-SAW detection */
3578 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3579 if (status < 0)
3580 goto error;
3581 /* sense threshold for sense pre-SAW detection */
3582 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3583 if (status < 0)
3584 goto error;
3585 status = SetIqmAf(state, true);
3586 if (status < 0)
3587 goto error;
3588
3589 status = write16(state, IQM_AF_AGC_RF__A, 0);
3590 if (status < 0)
3591 goto error;
3592
3593 /* Impulse noise cruncher setup */
3594 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3595 if (status < 0)
3596 goto error;
3597 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3598 if (status < 0)
3599 goto error;
3600 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3601 if (status < 0)
3602 goto error;
3603
3604 status = write16(state, IQM_RC_STRETCH__A, 16);
3605 if (status < 0)
3606 goto error;
3607 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3608 if (status < 0)
3609 goto error;
3610 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3611 if (status < 0)
3612 goto error;
3613 status = write16(state, IQM_CF_SCALE__A, 1600);
3614 if (status < 0)
3615 goto error;
3616 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3617 if (status < 0)
3618 goto error;
3619
3620 /* virtual clipping threshold for clipping ADC detection */
3621 status = write16(state, IQM_AF_CLP_TH__A, 448);
3622 if (status < 0)
3623 goto error;
3624 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3625 if (status < 0)
3626 goto error;
3627
3628 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3629 if (status < 0)
3630 goto error;
3631
3632 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3633 if (status < 0)
3634 goto error;
3635 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3636 if (status < 0)
3637 goto error;
3638 /* enable power measurement interrupt */
3639 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3640 if (status < 0)
3641 goto error;
3642 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3643 if (status < 0)
3644 goto error;
3645
3646 /* IQM will not be reset from here, sync ADC and update/init AGC */
3647 status = ADCSynchronization(state);
3648 if (status < 0)
3649 goto error;
3650 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3651 if (status < 0)
3652 goto error;
3653
3654 /* Halt SCU to enable safe non-atomic accesses */
3655 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3656 if (status < 0)
3657 goto error;
3658
3659 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3660 if (status < 0)
3661 goto error;
3662 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3663 if (status < 0)
3664 goto error;
3665
3666 /* Set Noise Estimation notch width and enable DC fix */
3667 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3668 if (status < 0)
3669 goto error;
3670 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3671 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3672 if (status < 0)
3673 goto error;
3674
3675 /* Activate SCU to enable SCU commands */
3676 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3677 if (status < 0)
3678 goto error;
3679
3680 if (!state->m_DRXK_A3_ROM_CODE) {
3681 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3682 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3683 if (status < 0)
3684 goto error;
3685 }
3686
3687 /* OFDM_SC setup */
3688#ifdef COMPILE_FOR_NONRT
3689 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3690 if (status < 0)
3691 goto error;
3692 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3693 if (status < 0)
3694 goto error;
3695#endif
3696
3697 /* FEC setup */
3698 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3699 if (status < 0)
3700 goto error;
3701
3702
3703#ifdef COMPILE_FOR_NONRT
3704 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3705 if (status < 0)
3706 goto error;
3707#else
3708 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3709 if (status < 0)
3710 goto error;
3711#endif
3712 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3713 if (status < 0)
3714 goto error;
3715
3716 /* Setup MPEG bus */
3717 status = MPEGTSDtoSetup(state, OM_DVBT);
3718 if (status < 0)
3719 goto error;
3720 /* Set DVBT Presets */
3721 status = DVBTActivatePresets(state);
3722 if (status < 0)
3723 goto error;
3724
3725error:
3726 if (status < 0)
3727 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003728 return status;
3729}
3730
3731/*============================================================================*/
3732/**
3733* \brief Start dvbt demodulating for channel.
3734* \param demod instance of demodulator.
3735* \return DRXStatus_t.
3736*/
3737static int DVBTStart(struct drxk_state *state)
3738{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003739 u16 param1;
3740 int status;
3741 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003742
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003743 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003744 /* Start correct processes to get in lock */
3745 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003746 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3747 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3748 if (status < 0)
3749 goto error;
3750 /* Start FEC OC */
3751 status = MPEGTSStart(state);
3752 if (status < 0)
3753 goto error;
3754 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3755 if (status < 0)
3756 goto error;
3757error:
3758 if (status < 0)
3759 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003760 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003761}
3762
3763
3764/*============================================================================*/
3765
3766/**
3767* \brief Set up dvbt demodulator for channel.
3768* \param demod instance of demodulator.
3769* \return DRXStatus_t.
3770* // original DVBTSetChannel()
3771*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003772static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3773 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003774{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003775 u16 cmdResult = 0;
3776 u16 transmissionParams = 0;
3777 u16 operationMode = 0;
3778 u32 iqmRcRateOfs = 0;
3779 u32 bandwidth = 0;
3780 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003781 int status;
3782
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003783 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003784
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003785 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3786 if (status < 0)
3787 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003788
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003789 /* Halt SCU to enable safe non-atomic accesses */
3790 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3791 if (status < 0)
3792 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003793
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003794 /* Stop processors */
3795 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3796 if (status < 0)
3797 goto error;
3798 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3799 if (status < 0)
3800 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003801
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003802 /* Mandatory fix, always stop CP, required to set spl offset back to
3803 hardware default (is set to 0 by ucode during pilot detection */
3804 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3805 if (status < 0)
3806 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003807
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003808 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003809
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003810 /* mode */
3811 switch (state->param.u.ofdm.transmission_mode) {
3812 case TRANSMISSION_MODE_AUTO:
3813 default:
3814 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3815 /* fall through , try first guess DRX_FFTMODE_8K */
3816 case TRANSMISSION_MODE_8K:
3817 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
3818 goto error;
3819 case TRANSMISSION_MODE_2K:
3820 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
3821 goto error;
3822 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003823
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003824 /* guard */
3825 switch (state->param.u.ofdm.guard_interval) {
3826 default:
3827 case GUARD_INTERVAL_AUTO:
3828 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3829 /* fall through , try first guess DRX_GUARD_1DIV4 */
3830 case GUARD_INTERVAL_1_4:
3831 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
3832 goto error;
3833 case GUARD_INTERVAL_1_32:
3834 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
3835 goto error;
3836 case GUARD_INTERVAL_1_16:
3837 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
3838 goto error;
3839 case GUARD_INTERVAL_1_8:
3840 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
3841 goto error;
3842 }
3843
3844 /* hierarchy */
3845 switch (state->param.u.ofdm.hierarchy_information) {
3846 case HIERARCHY_AUTO:
3847 case HIERARCHY_NONE:
3848 default:
3849 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3850 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3851 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3852 /* break; */
3853 case HIERARCHY_1:
3854 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3855 break;
3856 case HIERARCHY_2:
3857 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3858 break;
3859 case HIERARCHY_4:
3860 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3861 break;
3862 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003863
3864
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003865 /* constellation */
3866 switch (state->param.u.ofdm.constellation) {
3867 case QAM_AUTO:
3868 default:
3869 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3870 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3871 case QAM_64:
3872 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3873 break;
3874 case QPSK:
3875 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3876 break;
3877 case QAM_16:
3878 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3879 break;
3880 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003881#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003882 /* No hierachical channels support in BDA */
3883 /* Priority (only for hierarchical channels) */
3884 switch (channel->priority) {
3885 case DRX_PRIORITY_LOW:
3886 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3887 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3888 OFDM_EC_SB_PRIOR_LO);
3889 break;
3890 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003891 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003892 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3893 OFDM_EC_SB_PRIOR_HI));
3894 break;
3895 case DRX_PRIORITY_UNKNOWN: /* fall through */
3896 default:
3897 status = -EINVAL;
3898 goto error;
3899 }
3900#else
3901 /* Set Priorty high */
3902 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3903 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3904 if (status < 0)
3905 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003906#endif
3907
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003908 /* coderate */
3909 switch (state->param.u.ofdm.code_rate_HP) {
3910 case FEC_AUTO:
3911 default:
3912 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3913 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3914 case FEC_2_3:
3915 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3916 break;
3917 case FEC_1_2:
3918 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3919 break;
3920 case FEC_3_4:
3921 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3922 break;
3923 case FEC_5_6:
3924 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3925 break;
3926 case FEC_7_8:
3927 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3928 break;
3929 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003930
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003931 /* SAW filter selection: normaly not necesarry, but if wanted
3932 the application can select a SAW filter via the driver by using UIOs */
3933 /* First determine real bandwidth (Hz) */
3934 /* Also set delay for impulse noise cruncher */
3935 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3936 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3937 functions */
3938 switch (state->param.u.ofdm.bandwidth) {
3939 case BANDWIDTH_AUTO:
3940 case BANDWIDTH_8_MHZ:
3941 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3942 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003943 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003944 goto error;
3945 /* cochannel protection for PAL 8 MHz */
3946 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3947 if (status < 0)
3948 goto error;
3949 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3950 if (status < 0)
3951 goto error;
3952 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3953 if (status < 0)
3954 goto error;
3955 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3956 if (status < 0)
3957 goto error;
3958 break;
3959 case BANDWIDTH_7_MHZ:
3960 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3961 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3962 if (status < 0)
3963 goto error;
3964 /* cochannel protection for PAL 7 MHz */
3965 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3966 if (status < 0)
3967 goto error;
3968 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3969 if (status < 0)
3970 goto error;
3971 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3972 if (status < 0)
3973 goto error;
3974 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3975 if (status < 0)
3976 goto error;
3977 break;
3978 case BANDWIDTH_6_MHZ:
3979 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3980 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3981 if (status < 0)
3982 goto error;
3983 /* cochannel protection for NTSC 6 MHz */
3984 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3985 if (status < 0)
3986 goto error;
3987 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3988 if (status < 0)
3989 goto error;
3990 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3991 if (status < 0)
3992 goto error;
3993 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3994 if (status < 0)
3995 goto error;
3996 break;
3997 default:
3998 status = -EINVAL;
3999 goto error;
4000 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004001
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004002 if (iqmRcRateOfs == 0) {
4003 /* Now compute IQM_RC_RATE_OFS
4004 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4005 =>
4006 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4007 */
4008 /* (SysFreq / BandWidth) * (2^28) */
4009 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4010 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4011 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4012 iqmRcRateOfs = Frac28a((u32)
4013 ((state->m_sysClockFreq *
4014 1000) / 3), bandwidth);
4015 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4016 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4017 iqmRcRateOfs += 0x80L;
4018 iqmRcRateOfs = iqmRcRateOfs >> 7;
4019 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4020 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4021 }
4022
4023 iqmRcRateOfs &=
4024 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4025 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4026 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4027 if (status < 0)
4028 goto error;
4029
4030 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004031
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004032#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004033 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4034 if (status < 0)
4035 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004036#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004037 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4038 if (status < 0)
4039 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004040
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004041 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004042
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004043 /* Activate SCU to enable SCU commands */
4044 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4045 if (status < 0)
4046 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004047
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004048 /* Enable SC after setting all other parameters */
4049 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4050 if (status < 0)
4051 goto error;
4052 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4053 if (status < 0)
4054 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004055
4056
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004057 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4058 if (status < 0)
4059 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004060
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004061 /* Write SC parameter registers, set all AUTO flags in operation mode */
4062 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4063 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4064 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4065 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4066 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4067 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4068 0, transmissionParams, param1, 0, 0, 0);
4069 if (status < 0)
4070 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004071
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004072 if (!state->m_DRXK_A3_ROM_CODE)
4073 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4074error:
4075 if (status < 0)
4076 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004077
4078 return status;
4079}
4080
4081
4082/*============================================================================*/
4083
4084/**
4085* \brief Retreive lock status .
4086* \param demod Pointer to demodulator instance.
4087* \param lockStat Pointer to lock status structure.
4088* \return DRXStatus_t.
4089*
4090*/
4091static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4092{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004093 int status;
4094 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4095 OFDM_SC_RA_RAM_LOCK_FEC__M);
4096 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4097 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004098
Oliver Endrissebc7de22011-07-03 13:49:44 -03004099 u16 ScRaRamLock = 0;
4100 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004101
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004102 dprintk(1, "\n");
4103
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004104 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004105 /* driver 0.9.0 */
4106 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004107 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004108 if (status < 0)
4109 goto end;
4110 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4111 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004112
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004113 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004114 if (status < 0)
4115 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004116
Oliver Endrissebc7de22011-07-03 13:49:44 -03004117 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4118 *pLockStatus = MPEG_LOCK;
4119 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4120 *pLockStatus = FEC_LOCK;
4121 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4122 *pLockStatus = DEMOD_LOCK;
4123 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4124 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004125end:
4126 if (status < 0)
4127 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004128
Oliver Endrissebc7de22011-07-03 13:49:44 -03004129 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004130}
4131
Oliver Endrissebc7de22011-07-03 13:49:44 -03004132static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004133{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004134 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004135 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004136
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004137 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004138 status = CtrlPowerMode(state, &powerMode);
4139 if (status < 0)
4140 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004141
Oliver Endrissebc7de22011-07-03 13:49:44 -03004142 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004143}
4144
4145
Oliver Endrissebc7de22011-07-03 13:49:44 -03004146/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004147static int PowerDownQAM(struct drxk_state *state)
4148{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004149 u16 data = 0;
4150 u16 cmdResult;
4151 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004152
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004153 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004154 status = read16(state, SCU_COMM_EXEC__A, &data);
4155 if (status < 0)
4156 goto error;
4157 if (data == SCU_COMM_EXEC_ACTIVE) {
4158 /*
4159 STOP demodulator
4160 QAM and HW blocks
4161 */
4162 /* stop all comstate->m_exec */
4163 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004164 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004165 goto error;
4166 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 -03004167 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004168 goto error;
4169 }
4170 /* powerdown AFE */
4171 status = SetIqmAf(state, false);
4172
4173error:
4174 if (status < 0)
4175 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004176
Oliver Endrissebc7de22011-07-03 13:49:44 -03004177 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004178}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004179
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004180/*============================================================================*/
4181
4182/**
4183* \brief Setup of the QAM Measurement intervals for signal quality
4184* \param demod instance of demod.
4185* \param constellation current constellation.
4186* \return DRXStatus_t.
4187*
4188* NOTE:
4189* Take into account that for certain settings the errorcounters can overflow.
4190* The implementation does not check this.
4191*
4192*/
4193static int SetQAMMeasurement(struct drxk_state *state,
4194 enum EDrxkConstellation constellation,
4195 u32 symbolRate)
4196{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004197 u32 fecBitsDesired = 0; /* BER accounting period */
4198 u32 fecRsPeriodTotal = 0; /* Total period */
4199 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4200 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004201 int status = 0;
4202
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004203 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004204
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004205 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004206 /* fecBitsDesired = symbolRate [kHz] *
4207 FrameLenght [ms] *
4208 (constellation + 1) *
4209 SyncLoss (== 1) *
4210 ViterbiLoss (==1)
4211 */
4212 switch (constellation) {
4213 case DRX_CONSTELLATION_QAM16:
4214 fecBitsDesired = 4 * symbolRate;
4215 break;
4216 case DRX_CONSTELLATION_QAM32:
4217 fecBitsDesired = 5 * symbolRate;
4218 break;
4219 case DRX_CONSTELLATION_QAM64:
4220 fecBitsDesired = 6 * symbolRate;
4221 break;
4222 case DRX_CONSTELLATION_QAM128:
4223 fecBitsDesired = 7 * symbolRate;
4224 break;
4225 case DRX_CONSTELLATION_QAM256:
4226 fecBitsDesired = 8 * symbolRate;
4227 break;
4228 default:
4229 status = -EINVAL;
4230 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004231 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004232 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004233
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004234 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4235 fecBitsDesired *= 500; /* meas. period [ms] */
4236
4237 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4238 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4239 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4240
4241 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4242 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4243 if (fecRsPrescale == 0) {
4244 /* Divide by zero (though impossible) */
4245 status = -EINVAL;
4246 if (status < 0)
4247 goto error;
4248 }
4249 fecRsPeriod =
4250 ((u16) fecRsPeriodTotal +
4251 (fecRsPrescale >> 1)) / fecRsPrescale;
4252
4253 /* write corresponding registers */
4254 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4255 if (status < 0)
4256 goto error;
4257 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4258 if (status < 0)
4259 goto error;
4260 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4261error:
4262 if (status < 0)
4263 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004264 return status;
4265}
4266
Oliver Endrissebc7de22011-07-03 13:49:44 -03004267static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004268{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004269 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004270
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004271 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004272 /* QAM Equalizer Setup */
4273 /* Equalizer */
4274 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4275 if (status < 0)
4276 goto error;
4277 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4278 if (status < 0)
4279 goto error;
4280 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4281 if (status < 0)
4282 goto error;
4283 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4284 if (status < 0)
4285 goto error;
4286 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4287 if (status < 0)
4288 goto error;
4289 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4290 if (status < 0)
4291 goto error;
4292 /* Decision Feedback Equalizer */
4293 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4294 if (status < 0)
4295 goto error;
4296 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4297 if (status < 0)
4298 goto error;
4299 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4300 if (status < 0)
4301 goto error;
4302 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4303 if (status < 0)
4304 goto error;
4305 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4306 if (status < 0)
4307 goto error;
4308 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4309 if (status < 0)
4310 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004311
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004312 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4313 if (status < 0)
4314 goto error;
4315 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4316 if (status < 0)
4317 goto error;
4318 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4319 if (status < 0)
4320 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004321
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004322 /* QAM Slicer Settings */
4323 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4324 if (status < 0)
4325 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004326
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004327 /* QAM Loop Controller Coeficients */
4328 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4329 if (status < 0)
4330 goto error;
4331 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4332 if (status < 0)
4333 goto error;
4334 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4335 if (status < 0)
4336 goto error;
4337 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4338 if (status < 0)
4339 goto error;
4340 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4341 if (status < 0)
4342 goto error;
4343 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4344 if (status < 0)
4345 goto error;
4346 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4347 if (status < 0)
4348 goto error;
4349 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4350 if (status < 0)
4351 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004352
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004353 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4354 if (status < 0)
4355 goto error;
4356 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4357 if (status < 0)
4358 goto error;
4359 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4360 if (status < 0)
4361 goto error;
4362 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4363 if (status < 0)
4364 goto error;
4365 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4366 if (status < 0)
4367 goto error;
4368 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4369 if (status < 0)
4370 goto error;
4371 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4372 if (status < 0)
4373 goto error;
4374 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4375 if (status < 0)
4376 goto error;
4377 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4378 if (status < 0)
4379 goto error;
4380 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4381 if (status < 0)
4382 goto error;
4383 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4384 if (status < 0)
4385 goto error;
4386 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4387 if (status < 0)
4388 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004389
4390
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004391 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004392
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004393 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4394 if (status < 0)
4395 goto error;
4396 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4397 if (status < 0)
4398 goto error;
4399 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4400 if (status < 0)
4401 goto error;
4402 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4403 if (status < 0)
4404 goto error;
4405 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4406 if (status < 0)
4407 goto error;
4408 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4409 if (status < 0)
4410 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004411
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004412 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4413 if (status < 0)
4414 goto error;
4415 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4416 if (status < 0)
4417 goto error;
4418 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4419 if (status < 0)
4420 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004421
4422
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004423 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004424
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004425 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4426 if (status < 0)
4427 goto error;
4428 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4429 if (status < 0)
4430 goto error;
4431 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4432 if (status < 0)
4433 goto error;
4434 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4435 if (status < 0)
4436 goto error;
4437 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4438 if (status < 0)
4439 goto error;
4440 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4441 if (status < 0)
4442 goto error;
4443 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4444 if (status < 0)
4445 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004446
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004447error:
4448 if (status < 0)
4449 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004450 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004451}
4452
4453/*============================================================================*/
4454
4455/**
4456* \brief QAM32 specific setup
4457* \param demod instance of demod.
4458* \return DRXStatus_t.
4459*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004460static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004461{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004462 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004463
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004464 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004465
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004466 /* QAM Equalizer Setup */
4467 /* Equalizer */
4468 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4469 if (status < 0)
4470 goto error;
4471 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4472 if (status < 0)
4473 goto error;
4474 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4475 if (status < 0)
4476 goto error;
4477 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4478 if (status < 0)
4479 goto error;
4480 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4481 if (status < 0)
4482 goto error;
4483 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4484 if (status < 0)
4485 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004486
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004487 /* Decision Feedback Equalizer */
4488 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4489 if (status < 0)
4490 goto error;
4491 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4492 if (status < 0)
4493 goto error;
4494 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4495 if (status < 0)
4496 goto error;
4497 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4498 if (status < 0)
4499 goto error;
4500 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4501 if (status < 0)
4502 goto error;
4503 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4504 if (status < 0)
4505 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004506
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004507 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4508 if (status < 0)
4509 goto error;
4510 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4511 if (status < 0)
4512 goto error;
4513 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4514 if (status < 0)
4515 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004516
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004517 /* QAM Slicer Settings */
4518
4519 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4520 if (status < 0)
4521 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004522
4523
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004524 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004525
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004526 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4527 if (status < 0)
4528 goto error;
4529 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4530 if (status < 0)
4531 goto error;
4532 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4533 if (status < 0)
4534 goto error;
4535 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4536 if (status < 0)
4537 goto error;
4538 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4539 if (status < 0)
4540 goto error;
4541 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4542 if (status < 0)
4543 goto error;
4544 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4545 if (status < 0)
4546 goto error;
4547 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4548 if (status < 0)
4549 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004550
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004551 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4552 if (status < 0)
4553 goto error;
4554 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4555 if (status < 0)
4556 goto error;
4557 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4558 if (status < 0)
4559 goto error;
4560 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4561 if (status < 0)
4562 goto error;
4563 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4564 if (status < 0)
4565 goto error;
4566 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4567 if (status < 0)
4568 goto error;
4569 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4570 if (status < 0)
4571 goto error;
4572 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4573 if (status < 0)
4574 goto error;
4575 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4576 if (status < 0)
4577 goto error;
4578 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4579 if (status < 0)
4580 goto error;
4581 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4582 if (status < 0)
4583 goto error;
4584 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4585 if (status < 0)
4586 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004587
4588
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004589 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004590
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004591 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4592 if (status < 0)
4593 goto error;
4594 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4595 if (status < 0)
4596 goto error;
4597 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4598 if (status < 0)
4599 goto error;
4600 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4601 if (status < 0)
4602 goto error;
4603 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4604 if (status < 0)
4605 goto error;
4606 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4607 if (status < 0)
4608 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004609
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004610 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4611 if (status < 0)
4612 goto error;
4613 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4614 if (status < 0)
4615 goto error;
4616 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4617 if (status < 0)
4618 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004619
4620
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004621 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004622
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004623 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4624 if (status < 0)
4625 goto error;
4626 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4627 if (status < 0)
4628 goto error;
4629 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4630 if (status < 0)
4631 goto error;
4632 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4633 if (status < 0)
4634 goto error;
4635 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4636 if (status < 0)
4637 goto error;
4638 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4639 if (status < 0)
4640 goto error;
4641 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4642error:
4643 if (status < 0)
4644 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004645 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004646}
4647
4648/*============================================================================*/
4649
4650/**
4651* \brief QAM64 specific setup
4652* \param demod instance of demod.
4653* \return DRXStatus_t.
4654*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004655static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004656{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004657 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004658
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004659 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004660 /* QAM Equalizer Setup */
4661 /* Equalizer */
4662 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4663 if (status < 0)
4664 goto error;
4665 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4666 if (status < 0)
4667 goto error;
4668 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4669 if (status < 0)
4670 goto error;
4671 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4672 if (status < 0)
4673 goto error;
4674 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4675 if (status < 0)
4676 goto error;
4677 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4678 if (status < 0)
4679 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004680
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004681 /* Decision Feedback Equalizer */
4682 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4683 if (status < 0)
4684 goto error;
4685 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4686 if (status < 0)
4687 goto error;
4688 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4689 if (status < 0)
4690 goto error;
4691 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4692 if (status < 0)
4693 goto error;
4694 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4695 if (status < 0)
4696 goto error;
4697 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4698 if (status < 0)
4699 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004700
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004701 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4702 if (status < 0)
4703 goto error;
4704 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4705 if (status < 0)
4706 goto error;
4707 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4708 if (status < 0)
4709 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004710
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004711 /* QAM Slicer Settings */
4712 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4713 if (status < 0)
4714 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004715
4716
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004717 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004718
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004719 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4720 if (status < 0)
4721 goto error;
4722 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4723 if (status < 0)
4724 goto error;
4725 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4726 if (status < 0)
4727 goto error;
4728 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4729 if (status < 0)
4730 goto error;
4731 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4732 if (status < 0)
4733 goto error;
4734 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4735 if (status < 0)
4736 goto error;
4737 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4738 if (status < 0)
4739 goto error;
4740 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4741 if (status < 0)
4742 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004743
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004744 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4745 if (status < 0)
4746 goto error;
4747 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4748 if (status < 0)
4749 goto error;
4750 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4751 if (status < 0)
4752 goto error;
4753 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4754 if (status < 0)
4755 goto error;
4756 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4757 if (status < 0)
4758 goto error;
4759 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4760 if (status < 0)
4761 goto error;
4762 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4763 if (status < 0)
4764 goto error;
4765 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4766 if (status < 0)
4767 goto error;
4768 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4769 if (status < 0)
4770 goto error;
4771 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4772 if (status < 0)
4773 goto error;
4774 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4775 if (status < 0)
4776 goto error;
4777 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4778 if (status < 0)
4779 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004780
4781
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004782 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004783
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004784 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4785 if (status < 0)
4786 goto error;
4787 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4788 if (status < 0)
4789 goto error;
4790 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4791 if (status < 0)
4792 goto error;
4793 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4794 if (status < 0)
4795 goto error;
4796 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4797 if (status < 0)
4798 goto error;
4799 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4800 if (status < 0)
4801 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004802
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004803 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4804 if (status < 0)
4805 goto error;
4806 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4807 if (status < 0)
4808 goto error;
4809 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4810 if (status < 0)
4811 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004812
4813
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004814 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004815
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004816 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4817 if (status < 0)
4818 goto error;
4819 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4820 if (status < 0)
4821 goto error;
4822 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4823 if (status < 0)
4824 goto error;
4825 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4826 if (status < 0)
4827 goto error;
4828 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4829 if (status < 0)
4830 goto error;
4831 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4832 if (status < 0)
4833 goto error;
4834 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4835error:
4836 if (status < 0)
4837 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004838
Oliver Endrissebc7de22011-07-03 13:49:44 -03004839 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004840}
4841
4842/*============================================================================*/
4843
4844/**
4845* \brief QAM128 specific setup
4846* \param demod: instance of demod.
4847* \return DRXStatus_t.
4848*/
4849static int SetQAM128(struct drxk_state *state)
4850{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004851 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004852
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004853 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004854 /* QAM Equalizer Setup */
4855 /* Equalizer */
4856 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4857 if (status < 0)
4858 goto error;
4859 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4860 if (status < 0)
4861 goto error;
4862 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4863 if (status < 0)
4864 goto error;
4865 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4866 if (status < 0)
4867 goto error;
4868 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4869 if (status < 0)
4870 goto error;
4871 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4872 if (status < 0)
4873 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004874
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004875 /* Decision Feedback Equalizer */
4876 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4877 if (status < 0)
4878 goto error;
4879 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4880 if (status < 0)
4881 goto error;
4882 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4883 if (status < 0)
4884 goto error;
4885 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4886 if (status < 0)
4887 goto error;
4888 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4889 if (status < 0)
4890 goto error;
4891 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4892 if (status < 0)
4893 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004894
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004895 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4896 if (status < 0)
4897 goto error;
4898 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4899 if (status < 0)
4900 goto error;
4901 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4902 if (status < 0)
4903 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004904
4905
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004906 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004907
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004908 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4909 if (status < 0)
4910 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004911
4912
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004913 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004914
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004915 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4916 if (status < 0)
4917 goto error;
4918 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4919 if (status < 0)
4920 goto error;
4921 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4922 if (status < 0)
4923 goto error;
4924 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4925 if (status < 0)
4926 goto error;
4927 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4928 if (status < 0)
4929 goto error;
4930 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4931 if (status < 0)
4932 goto error;
4933 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4934 if (status < 0)
4935 goto error;
4936 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4937 if (status < 0)
4938 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004939
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004940 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4941 if (status < 0)
4942 goto error;
4943 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4944 if (status < 0)
4945 goto error;
4946 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4947 if (status < 0)
4948 goto error;
4949 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4950 if (status < 0)
4951 goto error;
4952 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4953 if (status < 0)
4954 goto error;
4955 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4956 if (status < 0)
4957 goto error;
4958 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4959 if (status < 0)
4960 goto error;
4961 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4962 if (status < 0)
4963 goto error;
4964 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4965 if (status < 0)
4966 goto error;
4967 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4968 if (status < 0)
4969 goto error;
4970 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4971 if (status < 0)
4972 goto error;
4973 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4974 if (status < 0)
4975 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004976
4977
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004978 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004979
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004980 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4981 if (status < 0)
4982 goto error;
4983 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4984 if (status < 0)
4985 goto error;
4986 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4987 if (status < 0)
4988 goto error;
4989 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4990 if (status < 0)
4991 goto error;
4992 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4993 if (status < 0)
4994 goto error;
4995 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4996 if (status < 0)
4997 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004998
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004999 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5000 if (status < 0)
5001 goto error;
5002 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5003 if (status < 0)
5004 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005005
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005006 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5007 if (status < 0)
5008 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005009
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005010 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005011
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005012 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5013 if (status < 0)
5014 goto error;
5015 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5016 if (status < 0)
5017 goto error;
5018 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5019 if (status < 0)
5020 goto error;
5021 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5022 if (status < 0)
5023 goto error;
5024 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5025 if (status < 0)
5026 goto error;
5027 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5028 if (status < 0)
5029 goto error;
5030 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5031error:
5032 if (status < 0)
5033 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005034
Oliver Endrissebc7de22011-07-03 13:49:44 -03005035 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005036}
5037
5038/*============================================================================*/
5039
5040/**
5041* \brief QAM256 specific setup
5042* \param demod: instance of demod.
5043* \return DRXStatus_t.
5044*/
5045static int SetQAM256(struct drxk_state *state)
5046{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005047 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005048
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005049 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005050 /* QAM Equalizer Setup */
5051 /* Equalizer */
5052 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5053 if (status < 0)
5054 goto error;
5055 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5056 if (status < 0)
5057 goto error;
5058 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5059 if (status < 0)
5060 goto error;
5061 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5062 if (status < 0)
5063 goto error;
5064 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5065 if (status < 0)
5066 goto error;
5067 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5068 if (status < 0)
5069 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005070
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005071 /* Decision Feedback Equalizer */
5072 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5073 if (status < 0)
5074 goto error;
5075 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5076 if (status < 0)
5077 goto error;
5078 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5079 if (status < 0)
5080 goto error;
5081 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5082 if (status < 0)
5083 goto error;
5084 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5085 if (status < 0)
5086 goto error;
5087 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5088 if (status < 0)
5089 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005090
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005091 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5092 if (status < 0)
5093 goto error;
5094 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5095 if (status < 0)
5096 goto error;
5097 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5098 if (status < 0)
5099 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005100
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005101 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005102
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005103 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5104 if (status < 0)
5105 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005106
5107
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005108 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005109
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005110 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5111 if (status < 0)
5112 goto error;
5113 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5114 if (status < 0)
5115 goto error;
5116 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5117 if (status < 0)
5118 goto error;
5119 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5120 if (status < 0)
5121 goto error;
5122 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5123 if (status < 0)
5124 goto error;
5125 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5126 if (status < 0)
5127 goto error;
5128 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5129 if (status < 0)
5130 goto error;
5131 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5132 if (status < 0)
5133 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005134
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005135 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5136 if (status < 0)
5137 goto error;
5138 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5139 if (status < 0)
5140 goto error;
5141 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5142 if (status < 0)
5143 goto error;
5144 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5145 if (status < 0)
5146 goto error;
5147 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5148 if (status < 0)
5149 goto error;
5150 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5151 if (status < 0)
5152 goto error;
5153 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5154 if (status < 0)
5155 goto error;
5156 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5157 if (status < 0)
5158 goto error;
5159 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5160 if (status < 0)
5161 goto error;
5162 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5163 if (status < 0)
5164 goto error;
5165 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5166 if (status < 0)
5167 goto error;
5168 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5169 if (status < 0)
5170 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005171
5172
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005173 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005174
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005175 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5176 if (status < 0)
5177 goto error;
5178 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5179 if (status < 0)
5180 goto error;
5181 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5182 if (status < 0)
5183 goto error;
5184 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5185 if (status < 0)
5186 goto error;
5187 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5188 if (status < 0)
5189 goto error;
5190 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5191 if (status < 0)
5192 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005193
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005194 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5195 if (status < 0)
5196 goto error;
5197 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5198 if (status < 0)
5199 goto error;
5200 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5201 if (status < 0)
5202 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005203
5204
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005205 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005206
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005207 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5208 if (status < 0)
5209 goto error;
5210 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5211 if (status < 0)
5212 goto error;
5213 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5214 if (status < 0)
5215 goto error;
5216 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5217 if (status < 0)
5218 goto error;
5219 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5220 if (status < 0)
5221 goto error;
5222 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5223 if (status < 0)
5224 goto error;
5225 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5226error:
5227 if (status < 0)
5228 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005229 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005230}
5231
5232
5233/*============================================================================*/
5234/**
5235* \brief Reset QAM block.
5236* \param demod: instance of demod.
5237* \param channel: pointer to channel data.
5238* \return DRXStatus_t.
5239*/
5240static int QAMResetQAM(struct drxk_state *state)
5241{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005242 int status;
5243 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005244
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005245 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005246 /* Stop QAM comstate->m_exec */
5247 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5248 if (status < 0)
5249 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005250
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005251 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5252error:
5253 if (status < 0)
5254 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005255 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005256}
5257
5258/*============================================================================*/
5259
5260/**
5261* \brief Set QAM symbolrate.
5262* \param demod: instance of demod.
5263* \param channel: pointer to channel data.
5264* \return DRXStatus_t.
5265*/
5266static int QAMSetSymbolrate(struct drxk_state *state)
5267{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005268 u32 adcFrequency = 0;
5269 u32 symbFreq = 0;
5270 u32 iqmRcRate = 0;
5271 u16 ratesel = 0;
5272 u32 lcSymbRate = 0;
5273 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005274
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005275 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005276 /* Select & calculate correct IQM rate */
5277 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5278 ratesel = 0;
5279 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
5280 if (state->param.u.qam.symbol_rate <= 1188750)
5281 ratesel = 3;
5282 else if (state->param.u.qam.symbol_rate <= 2377500)
5283 ratesel = 2;
5284 else if (state->param.u.qam.symbol_rate <= 4755000)
5285 ratesel = 1;
5286 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5287 if (status < 0)
5288 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005289
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005290 /*
5291 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5292 */
5293 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5294 if (symbFreq == 0) {
5295 /* Divide by zero */
5296 status = -EINVAL;
5297 goto error;
5298 }
5299 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5300 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5301 (1 << 23);
5302 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5303 if (status < 0)
5304 goto error;
5305 state->m_iqmRcRate = iqmRcRate;
5306 /*
5307 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5308 */
5309 symbFreq = state->param.u.qam.symbol_rate;
5310 if (adcFrequency == 0) {
5311 /* Divide by zero */
5312 status = -EINVAL;
5313 goto error;
5314 }
5315 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5316 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5317 16);
5318 if (lcSymbRate > 511)
5319 lcSymbRate = 511;
5320 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005321
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005322error:
5323 if (status < 0)
5324 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005325 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005326}
5327
5328/*============================================================================*/
5329
5330/**
5331* \brief Get QAM lock status.
5332* \param demod: instance of demod.
5333* \param channel: pointer to channel data.
5334* \return DRXStatus_t.
5335*/
5336
5337static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5338{
5339 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005340 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005341
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005342 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005343 *pLockStatus = NOT_LOCKED;
5344 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005345 SCU_RAM_COMMAND_STANDARD_QAM |
5346 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5347 Result);
5348 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005349 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005350
5351 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005352 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005353 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005354 /* 0x4000 DEMOD LOCKED */
5355 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005356 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005357 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5358 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005359 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005360 /* 0xC000 NEVER LOCKED */
5361 /* (system will never be able to lock to the signal) */
5362 /* TODO: check this, intermediate & standard specific lock states are not
5363 taken into account here */
5364 *pLockStatus = NEVER_LOCK;
5365 }
5366 return status;
5367}
5368
5369#define QAM_MIRROR__M 0x03
5370#define QAM_MIRROR_NORMAL 0x00
5371#define QAM_MIRRORED 0x01
5372#define QAM_MIRROR_AUTO_ON 0x02
5373#define QAM_LOCKRANGE__M 0x10
5374#define QAM_LOCKRANGE_NORMAL 0x10
5375
Oliver Endrissebc7de22011-07-03 13:49:44 -03005376static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5377 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005378{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005379 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005380 u8 parameterLen;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005381 u16 setEnvParameters[5];
5382 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5383 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005384
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005385 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005386 /*
5387 STEP 1: reset demodulator
5388 resets FEC DI and FEC RS
5389 resets QAM block
5390 resets SCU variables
5391 */
5392 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005393 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005394 goto error;
5395 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5396 if (status < 0)
5397 goto error;
5398 status = QAMResetQAM(state);
5399 if (status < 0)
5400 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005401
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005402 /*
5403 STEP 2: configure demodulator
5404 -set env
5405 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5406 */
5407 status = QAMSetSymbolrate(state);
5408 if (status < 0)
5409 goto error;
5410
5411 /* Env parameters */
5412 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
5413 if (state->m_OperationMode == OM_QAM_ITU_C)
5414 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
5415 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5416 /* check for LOCKRANGE Extented */
5417 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5418 parameterLen = 4;
5419
5420 /* Set params */
5421 switch (state->param.u.qam.modulation) {
5422 case QAM_256:
5423 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5424 break;
5425 case QAM_AUTO:
5426 case QAM_64:
5427 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5428 break;
5429 case QAM_16:
5430 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5431 break;
5432 case QAM_32:
5433 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5434 break;
5435 case QAM_128:
5436 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5437 break;
5438 default:
5439 status = -EINVAL;
5440 break;
5441 }
5442 if (status < 0)
5443 goto error;
5444 setParamParameters[0] = state->m_Constellation; /* constellation */
5445 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5446
5447 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5448 if (status < 0)
5449 goto error;
5450
5451
5452 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5453 setup constellation independent registers */
5454#if 0
5455 status = SetFrequency(channel, tunerFreqOffset));
5456 if (status < 0)
5457 goto error;
5458#endif
5459 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5460 if (status < 0)
5461 goto error;
5462
5463 /* Setup BER measurement */
5464 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5465 if (status < 0)
5466 goto error;
5467
5468 /* Reset default values */
5469 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5470 if (status < 0)
5471 goto error;
5472 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5473 if (status < 0)
5474 goto error;
5475
5476 /* Reset default LC values */
5477 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5478 if (status < 0)
5479 goto error;
5480 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5481 if (status < 0)
5482 goto error;
5483 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5484 if (status < 0)
5485 goto error;
5486 status = write16(state, QAM_LC_MODE__A, 7);
5487 if (status < 0)
5488 goto error;
5489
5490 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5491 if (status < 0)
5492 goto error;
5493 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5494 if (status < 0)
5495 goto error;
5496 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5497 if (status < 0)
5498 goto error;
5499 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5500 if (status < 0)
5501 goto error;
5502 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5503 if (status < 0)
5504 goto error;
5505 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5506 if (status < 0)
5507 goto error;
5508 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5509 if (status < 0)
5510 goto error;
5511 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5512 if (status < 0)
5513 goto error;
5514 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5515 if (status < 0)
5516 goto error;
5517 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5518 if (status < 0)
5519 goto error;
5520 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5521 if (status < 0)
5522 goto error;
5523 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5524 if (status < 0)
5525 goto error;
5526 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5527 if (status < 0)
5528 goto error;
5529 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5530 if (status < 0)
5531 goto error;
5532 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5533 if (status < 0)
5534 goto error;
5535
5536 /* Mirroring, QAM-block starting point not inverted */
5537 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5538 if (status < 0)
5539 goto error;
5540
5541 /* Halt SCU to enable safe non-atomic accesses */
5542 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5543 if (status < 0)
5544 goto error;
5545
5546 /* STEP 4: constellation specific setup */
5547 switch (state->param.u.qam.modulation) {
5548 case QAM_16:
5549 status = SetQAM16(state);
5550 break;
5551 case QAM_32:
5552 status = SetQAM32(state);
5553 break;
5554 case QAM_AUTO:
5555 case QAM_64:
5556 status = SetQAM64(state);
5557 break;
5558 case QAM_128:
5559 status = SetQAM128(state);
5560 break;
5561 case QAM_256:
5562 status = SetQAM256(state);
5563 break;
5564 default:
5565 status = -EINVAL;
5566 break;
5567 }
5568 if (status < 0)
5569 goto error;
5570
5571 /* Activate SCU to enable SCU commands */
5572 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5573 if (status < 0)
5574 goto error;
5575
5576 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5577 /* extAttr->currentChannel.constellation = channel->constellation; */
5578 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5579 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5580 if (status < 0)
5581 goto error;
5582
5583 /* Start processes */
5584 status = MPEGTSStart(state);
5585 if (status < 0)
5586 goto error;
5587 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5588 if (status < 0)
5589 goto error;
5590 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5591 if (status < 0)
5592 goto error;
5593 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5594 if (status < 0)
5595 goto error;
5596
5597 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5598 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5599 if (status < 0)
5600 goto error;
5601
5602 /* update global DRXK data container */
5603/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5604
5605error:
5606 if (status < 0)
5607 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005608 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005609}
5610
Oliver Endrissebc7de22011-07-03 13:49:44 -03005611static int SetQAMStandard(struct drxk_state *state,
5612 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005613{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005614 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005615#ifdef DRXK_QAM_TAPS
5616#define DRXK_QAMA_TAPS_SELECT
5617#include "drxk_filters.h"
5618#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005619#endif
5620
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005621 /* added antenna switch */
5622 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005623
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005624 /* Ensure correct power-up mode */
5625 status = PowerUpQAM(state);
5626 if (status < 0)
5627 goto error;
5628 /* Reset QAM block */
5629 status = QAMResetQAM(state);
5630 if (status < 0)
5631 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005632
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005633 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005634
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005635 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5636 if (status < 0)
5637 goto error;
5638 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5639 if (status < 0)
5640 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005641
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005642 /* Upload IQM Channel Filter settings by
5643 boot loader from ROM table */
5644 switch (oMode) {
5645 case OM_QAM_ITU_A:
5646 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5647 break;
5648 case OM_QAM_ITU_C:
5649 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 -03005650 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005651 goto error;
5652 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5653 break;
5654 default:
5655 status = -EINVAL;
5656 }
5657 if (status < 0)
5658 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005659
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005660 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5661 if (status < 0)
5662 goto error;
5663 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5664 if (status < 0)
5665 goto error;
5666 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5667 if (status < 0)
5668 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005669
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005670 status = write16(state, IQM_RC_STRETCH__A, 21);
5671 if (status < 0)
5672 goto error;
5673 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5674 if (status < 0)
5675 goto error;
5676 status = write16(state, IQM_AF_CLP_TH__A, 448);
5677 if (status < 0)
5678 goto error;
5679 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5680 if (status < 0)
5681 goto error;
5682 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5683 if (status < 0)
5684 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005685
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005686 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5687 if (status < 0)
5688 goto error;
5689 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5690 if (status < 0)
5691 goto error;
5692 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5693 if (status < 0)
5694 goto error;
5695 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5696 if (status < 0)
5697 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005698
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005699 /* IQM Impulse Noise Processing Unit */
5700 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5701 if (status < 0)
5702 goto error;
5703 status = write16(state, IQM_CF_DATATH__A, 1000);
5704 if (status < 0)
5705 goto error;
5706 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5707 if (status < 0)
5708 goto error;
5709 status = write16(state, IQM_CF_DET_LCT__A, 0);
5710 if (status < 0)
5711 goto error;
5712 status = write16(state, IQM_CF_WND_LEN__A, 1);
5713 if (status < 0)
5714 goto error;
5715 status = write16(state, IQM_CF_PKDTH__A, 1);
5716 if (status < 0)
5717 goto error;
5718 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5719 if (status < 0)
5720 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005721
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005722 /* turn on IQMAF. Must be done before setAgc**() */
5723 status = SetIqmAf(state, true);
5724 if (status < 0)
5725 goto error;
5726 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5727 if (status < 0)
5728 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005729
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005730 /* IQM will not be reset from here, sync ADC and update/init AGC */
5731 status = ADCSynchronization(state);
5732 if (status < 0)
5733 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005734
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005735 /* Set the FSM step period */
5736 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5737 if (status < 0)
5738 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005739
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005740 /* Halt SCU to enable safe non-atomic accesses */
5741 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5742 if (status < 0)
5743 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005744
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005745 /* No more resets of the IQM, current standard correctly set =>
5746 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005747
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005748 status = InitAGC(state, true);
5749 if (status < 0)
5750 goto error;
5751 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5752 if (status < 0)
5753 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005754
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005755 /* Configure AGC's */
5756 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5757 if (status < 0)
5758 goto error;
5759 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5760 if (status < 0)
5761 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005762
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005763 /* Activate SCU to enable SCU commands */
5764 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5765error:
5766 if (status < 0)
5767 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005768 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005769}
5770
5771static int WriteGPIO(struct drxk_state *state)
5772{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005773 int status;
5774 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005775
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005776 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005777 /* stop lock indicator process */
5778 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5779 if (status < 0)
5780 goto error;
5781
5782 /* Write magic word to enable pdr reg write */
5783 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5784 if (status < 0)
5785 goto error;
5786
5787 if (state->m_hasSAWSW) {
5788 /* write to io pad configuration register - output mode */
5789 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005790 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005791 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005792
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005793 /* use corresponding bit in io data output registar */
5794 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005795 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005796 goto error;
5797 if (state->m_GPIO == 0)
5798 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5799 else
5800 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5801 /* write back to io data output register */
5802 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005803 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005804 goto error;
5805
5806 }
5807 /* Write magic word to disable pdr reg write */
5808 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5809error:
5810 if (status < 0)
5811 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005812 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005813}
5814
5815static int SwitchAntennaToQAM(struct drxk_state *state)
5816{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005817 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005818
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005819 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005820
Oliver Endrissebc7de22011-07-03 13:49:44 -03005821 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5822 if (state->m_GPIO != state->m_AntennaDVBC) {
5823 state->m_GPIO = state->m_AntennaDVBC;
5824 status = WriteGPIO(state);
5825 }
5826 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005827 if (status < 0)
5828 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005829 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005830}
5831
5832static int SwitchAntennaToDVBT(struct drxk_state *state)
5833{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005834 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005835
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005836 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005837 if (state->m_AntennaSwitchDVBTDVBC != 0) {
5838 if (state->m_GPIO != state->m_AntennaDVBT) {
5839 state->m_GPIO = state->m_AntennaDVBT;
5840 status = WriteGPIO(state);
5841 }
5842 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005843 if (status < 0)
5844 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005845 return status;
5846}
5847
5848
5849static int PowerDownDevice(struct drxk_state *state)
5850{
5851 /* Power down to requested mode */
5852 /* Backup some register settings */
5853 /* Set pins with possible pull-ups connected to them in input mode */
5854 /* Analog power down */
5855 /* ADC power down */
5856 /* Power down device */
5857 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005858
5859 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005860 if (state->m_bPDownOpenBridge) {
5861 /* Open I2C bridge before power down of DRXK */
5862 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005863 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005864 goto error;
5865 }
5866 /* driver 0.9.0 */
5867 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005868 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005869 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005870
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005871 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5872 if (status < 0)
5873 goto error;
5874 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5875 if (status < 0)
5876 goto error;
5877 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5878 status = HI_CfgCommand(state);
5879error:
5880 if (status < 0)
5881 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5882
5883 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005884}
5885
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005886static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005887{
5888 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005889 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005890
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005891 dprintk(1, "\n");
5892
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005893 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5894 if (err < 0) {
5895 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005896 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005897 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005898 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005899 return err;
5900 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005901 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005902 release_firmware(fw);
5903 return err;
5904}
5905
5906static int init_drxk(struct drxk_state *state)
5907{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005908 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005909 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005910 u16 driverVersion;
5911
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005912 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005913 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005914 status = PowerUpDevice(state);
5915 if (status < 0)
5916 goto error;
5917 status = DRXX_Open(state);
5918 if (status < 0)
5919 goto error;
5920 /* Soft reset of OFDM-, sys- and osc-clockdomain */
5921 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);
5922 if (status < 0)
5923 goto error;
5924 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5925 if (status < 0)
5926 goto error;
5927 /* TODO is this needed, if yes how much delay in worst case scenario */
5928 msleep(1);
5929 state->m_DRXK_A3_PATCH_CODE = true;
5930 status = GetDeviceCapabilities(state);
5931 if (status < 0)
5932 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005933
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005934 /* Bridge delay, uses oscilator clock */
5935 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5936 /* SDA brdige delay */
5937 state->m_HICfgBridgeDelay =
5938 (u16) ((state->m_oscClockFreq / 1000) *
5939 HI_I2C_BRIDGE_DELAY) / 1000;
5940 /* Clipping */
5941 if (state->m_HICfgBridgeDelay >
5942 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03005943 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005944 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
5945 }
5946 /* SCL bridge delay, same as SDA for now */
5947 state->m_HICfgBridgeDelay +=
5948 state->m_HICfgBridgeDelay <<
5949 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005950
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005951 status = InitHI(state);
5952 if (status < 0)
5953 goto error;
5954 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005955#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005956 if (!(state->m_DRXK_A1_ROM_CODE)
5957 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005958#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005959 {
5960 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5961 if (status < 0)
5962 goto error;
5963 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005964
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005965 /* disable MPEG port */
5966 status = MPEGTSDisable(state);
5967 if (status < 0)
5968 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005969
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005970 /* Stop AUD and SCU */
5971 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
5972 if (status < 0)
5973 goto error;
5974 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
5975 if (status < 0)
5976 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005977
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005978 /* enable token-ring bus through OFDM block for possible ucode upload */
5979 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
5980 if (status < 0)
5981 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005982
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005983 /* include boot loader section */
5984 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
5985 if (status < 0)
5986 goto error;
5987 status = BLChainCmd(state, 0, 6, 100);
5988 if (status < 0)
5989 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005990
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005991 if (!state->microcode_name)
5992 load_microcode(state, "drxk_a3.mc");
5993 else
5994 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005995
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005996 /* disable token-ring bus through OFDM block for possible ucode upload */
5997 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
5998 if (status < 0)
5999 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006000
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006001 /* Run SCU for a little while to initialize microcode version numbers */
6002 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6003 if (status < 0)
6004 goto error;
6005 status = DRXX_Open(state);
6006 if (status < 0)
6007 goto error;
6008 /* added for test */
6009 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006010
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006011 powerMode = DRXK_POWER_DOWN_OFDM;
6012 status = CtrlPowerMode(state, &powerMode);
6013 if (status < 0)
6014 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006015
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006016 /* Stamp driver version number in SCU data RAM in BCD code
6017 Done to enable field application engineers to retreive drxdriver version
6018 via I2C from SCU RAM.
6019 Not using SCU command interface for SCU register access since no
6020 microcode may be present.
6021 */
6022 driverVersion =
6023 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6024 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6025 ((DRXK_VERSION_MAJOR % 10) << 4) +
6026 (DRXK_VERSION_MINOR % 10);
6027 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6028 if (status < 0)
6029 goto error;
6030 driverVersion =
6031 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6032 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6033 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6034 (DRXK_VERSION_PATCH % 10);
6035 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6036 if (status < 0)
6037 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006038
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006039 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6040 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6041 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006042
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006043 /* Dirty fix of default values for ROM/PATCH microcode
6044 Dirty because this fix makes it impossible to setup suitable values
6045 before calling DRX_Open. This solution requires changes to RF AGC speed
6046 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006047
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006048 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006049
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006050 /* Reset driver debug flags to 0 */
6051 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6052 if (status < 0)
6053 goto error;
6054 /* driver 0.9.0 */
6055 /* Setup FEC OC:
6056 NOTE: No more full FEC resets allowed afterwards!! */
6057 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6058 if (status < 0)
6059 goto error;
6060 /* MPEGTS functions are still the same */
6061 status = MPEGTSDtoInit(state);
6062 if (status < 0)
6063 goto error;
6064 status = MPEGTSStop(state);
6065 if (status < 0)
6066 goto error;
6067 status = MPEGTSConfigurePolarity(state);
6068 if (status < 0)
6069 goto error;
6070 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6071 if (status < 0)
6072 goto error;
6073 /* added: configure GPIO */
6074 status = WriteGPIO(state);
6075 if (status < 0)
6076 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006077
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006078 state->m_DrxkState = DRXK_STOPPED;
6079
6080 if (state->m_bPowerDown) {
6081 status = PowerDownDevice(state);
6082 if (status < 0)
6083 goto error;
6084 state->m_DrxkState = DRXK_POWERED_DOWN;
6085 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006086 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006087 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006088error:
6089 if (status < 0)
6090 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006091
6092 return 0;
6093}
6094
Oliver Endrissebc7de22011-07-03 13:49:44 -03006095static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006096{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006097 struct drxk_state *state = fe->demodulator_priv;
6098
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006099 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006100 kfree(state);
6101}
6102
Oliver Endrissebc7de22011-07-03 13:49:44 -03006103static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006104{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006105 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006106
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006107 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006108 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006109 return -EBUSY;
6110 SetOperationMode(state, OM_QAM_ITU_A);
6111 return 0;
6112}
6113
Oliver Endrissebc7de22011-07-03 13:49:44 -03006114static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006115{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006116 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006117
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006118 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006119 ShutDown(state);
6120 mutex_unlock(&state->ctlock);
6121 return 0;
6122}
6123
Oliver Endrissebc7de22011-07-03 13:49:44 -03006124static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006125{
6126 struct drxk_state *state = fe->demodulator_priv;
6127
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006128 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006129 return ConfigureI2CBridge(state, enable ? true : false);
6130}
6131
Oliver Endrissebc7de22011-07-03 13:49:44 -03006132static int drxk_set_parameters(struct dvb_frontend *fe,
6133 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006134{
6135 struct drxk_state *state = fe->demodulator_priv;
6136 u32 IF;
6137
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006138 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006139 if (fe->ops.i2c_gate_ctrl)
6140 fe->ops.i2c_gate_ctrl(fe, 1);
6141 if (fe->ops.tuner_ops.set_params)
6142 fe->ops.tuner_ops.set_params(fe, p);
6143 if (fe->ops.i2c_gate_ctrl)
6144 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006145 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006146 fe->ops.tuner_ops.get_frequency(fe, &IF);
6147 Start(state, 0, IF);
6148
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006149 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006150
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006151 return 0;
6152}
6153
Oliver Endrissebc7de22011-07-03 13:49:44 -03006154static int drxk_c_get_frontend(struct dvb_frontend *fe,
6155 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006156{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006157 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006158 return 0;
6159}
6160
6161static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6162{
6163 struct drxk_state *state = fe->demodulator_priv;
6164 u32 stat;
6165
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006166 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006167 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006168 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006169 if (stat == MPEG_LOCK)
6170 *status |= 0x1f;
6171 if (stat == FEC_LOCK)
6172 *status |= 0x0f;
6173 if (stat == DEMOD_LOCK)
6174 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006175 return 0;
6176}
6177
6178static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6179{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006180 dprintk(1, "\n");
6181
Oliver Endrissebc7de22011-07-03 13:49:44 -03006182 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006183 return 0;
6184}
6185
Oliver Endrissebc7de22011-07-03 13:49:44 -03006186static int drxk_read_signal_strength(struct dvb_frontend *fe,
6187 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006188{
6189 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006190 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006191
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006192 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006193 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006194 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006195 return 0;
6196}
6197
6198static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6199{
6200 struct drxk_state *state = fe->demodulator_priv;
6201 s32 snr2;
6202
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006203 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006204 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006205 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006206 return 0;
6207}
6208
6209static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6210{
6211 struct drxk_state *state = fe->demodulator_priv;
6212 u16 err;
6213
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006214 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006215 DVBTQAMGetAccPktErr(state, &err);
6216 *ucblocks = (u32) err;
6217 return 0;
6218}
6219
Oliver Endrissebc7de22011-07-03 13:49:44 -03006220static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6221 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006222{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006223 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006224 sets->min_delay_ms = 3000;
6225 sets->max_drift = 0;
6226 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006227 return 0;
6228}
6229
Oliver Endrissebc7de22011-07-03 13:49:44 -03006230static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006231{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006232#if 0
6233 struct drxk_state *state = fe->demodulator_priv;
6234
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006235 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006236 kfree(state);
6237#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006238}
6239
Oliver Endrissebc7de22011-07-03 13:49:44 -03006240static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006241{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006242 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006243
6244 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006245 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006246 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006247 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006248 return 0;
6249}
6250
Oliver Endrissebc7de22011-07-03 13:49:44 -03006251static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006252{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006253 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006254
6255 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006256 mutex_unlock(&state->ctlock);
6257 return 0;
6258}
6259
Oliver Endrissebc7de22011-07-03 13:49:44 -03006260static int drxk_t_get_frontend(struct dvb_frontend *fe,
6261 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006262{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006263 dprintk(1, "\n");
6264
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006265 return 0;
6266}
6267
6268static struct dvb_frontend_ops drxk_c_ops = {
6269 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006270 .name = "DRXK DVB-C",
6271 .type = FE_QAM,
6272 .frequency_stepsize = 62500,
6273 .frequency_min = 47000000,
6274 .frequency_max = 862000000,
6275 .symbol_rate_min = 870000,
6276 .symbol_rate_max = 11700000,
6277 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6278 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006279 .release = drxk_c_release,
6280 .init = drxk_c_init,
6281 .sleep = drxk_c_sleep,
6282 .i2c_gate_ctrl = drxk_gate_ctrl,
6283
6284 .set_frontend = drxk_set_parameters,
6285 .get_frontend = drxk_c_get_frontend,
6286 .get_tune_settings = drxk_c_get_tune_settings,
6287
6288 .read_status = drxk_read_status,
6289 .read_ber = drxk_read_ber,
6290 .read_signal_strength = drxk_read_signal_strength,
6291 .read_snr = drxk_read_snr,
6292 .read_ucblocks = drxk_read_ucblocks,
6293};
6294
6295static struct dvb_frontend_ops drxk_t_ops = {
6296 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006297 .name = "DRXK DVB-T",
6298 .type = FE_OFDM,
6299 .frequency_min = 47125000,
6300 .frequency_max = 865000000,
6301 .frequency_stepsize = 166667,
6302 .frequency_tolerance = 0,
6303 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6304 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6305 FE_CAN_FEC_AUTO |
6306 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6307 FE_CAN_QAM_AUTO |
6308 FE_CAN_TRANSMISSION_MODE_AUTO |
6309 FE_CAN_GUARD_INTERVAL_AUTO |
6310 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006311 .release = drxk_t_release,
6312 .init = drxk_t_init,
6313 .sleep = drxk_t_sleep,
6314 .i2c_gate_ctrl = drxk_gate_ctrl,
6315
6316 .set_frontend = drxk_set_parameters,
6317 .get_frontend = drxk_t_get_frontend,
6318
6319 .read_status = drxk_read_status,
6320 .read_ber = drxk_read_ber,
6321 .read_signal_strength = drxk_read_signal_strength,
6322 .read_snr = drxk_read_snr,
6323 .read_ucblocks = drxk_read_ucblocks,
6324};
6325
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006326struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6327 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006328 struct dvb_frontend **fe_t)
6329{
6330 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006331 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006332
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006333 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006334 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006335 if (!state)
6336 return NULL;
6337
Oliver Endrissebc7de22011-07-03 13:49:44 -03006338 state->i2c = i2c;
6339 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006340 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006341 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006342 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03006343 state->m_AntennaSwitchDVBTDVBC = config->antenna_uses_gpio;
6344 state->m_AntennaDVBC = config->antenna_dvbc;
6345 state->m_AntennaDVBT = config->antenna_dvbt;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006346
6347 mutex_init(&state->mutex);
6348 mutex_init(&state->ctlock);
6349
Oliver Endrissebc7de22011-07-03 13:49:44 -03006350 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6351 sizeof(struct dvb_frontend_ops));
6352 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6353 sizeof(struct dvb_frontend_ops));
6354 state->c_frontend.demodulator_priv = state;
6355 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006356
6357 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006358 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006359 goto error;
6360 *fe_t = &state->t_frontend;
6361 return &state->c_frontend;
6362
6363error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006364 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006365 kfree(state);
6366 return NULL;
6367}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006368EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006369
6370MODULE_DESCRIPTION("DRX-K driver");
6371MODULE_AUTHOR("Ralph Metzler");
6372MODULE_LICENSE("GPL");