blob: 217796dd49bf509bd58fd1a1ddee4f9023c88940 [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;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300666 u32 ulSerialMode = 1;
667 u32 ulInvertTSClock = 0;
668 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
669 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
670 u32 ulDVBTBitrate = 50000000;
671 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
672
673 u32 ulInsertRSByte = 0;
674
675 u32 ulRfMirror = 1;
676 u32 ulPowerDown = 0;
677
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300678 dprintk(1, "\n");
679
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300680 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300681 state->m_hasDVBT = false;
682 state->m_hasDVBC = false;
683 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300684 state->m_hasOOB = false;
685 state->m_hasAudio = false;
686
687 state->m_ChunkSize = 124;
688
689 state->m_oscClockFreq = 0;
690 state->m_smartAntInverted = false;
691 state->m_bPDownOpenBridge = false;
692
693 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300694 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300695 /* Timing div, 250ns/Psys */
696 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
697 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
698 HI_I2C_DELAY) / 1000;
699 /* Clipping */
700 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
701 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
702 state->m_HICfgWakeUpKey = (state->demod_address << 1);
703 /* port/bridge/power down ctrl */
704 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
705
706 state->m_bPowerDown = (ulPowerDown != 0);
707
708 state->m_DRXK_A1_PATCH_CODE = false;
709 state->m_DRXK_A1_ROM_CODE = false;
710 state->m_DRXK_A2_ROM_CODE = false;
711 state->m_DRXK_A3_ROM_CODE = false;
712 state->m_DRXK_A2_PATCH_CODE = false;
713 state->m_DRXK_A3_PATCH_CODE = false;
714
715 /* Init AGC and PGA parameters */
716 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300717 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
718 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
719 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
720 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
721 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300722 state->m_vsbPgaCfg = 140;
723
724 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300725 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
726 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
727 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
728 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
729 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
730 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
731 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
732 state->m_vsbPreSawCfg.reference = 0x07;
733 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300734
735 state->m_Quality83percent = DEFAULT_MER_83;
736 state->m_Quality93percent = DEFAULT_MER_93;
737 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
738 state->m_Quality83percent = ulQual83;
739 state->m_Quality93percent = ulQual93;
740 }
741
742 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300743 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
744 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
745 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
746 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
747 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300748
749 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300750 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
751 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
752 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
753 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
754 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
755 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
756 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
757 state->m_atvPreSawCfg.reference = 0x04;
758 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300759
760
761 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300762 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
763 state->m_dvbtRfAgcCfg.outputLevel = 0;
764 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
765 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
766 state->m_dvbtRfAgcCfg.top = 0x2100;
767 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
768 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300769
770
771 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300772 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
773 state->m_dvbtIfAgcCfg.outputLevel = 0;
774 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
775 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
776 state->m_dvbtIfAgcCfg.top = 13424;
777 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
778 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300779 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300780 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
781 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300782
Oliver Endrissebc7de22011-07-03 13:49:44 -0300783 state->m_dvbtPreSawCfg.reference = 4;
784 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300785
786 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300787 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
788 state->m_qamRfAgcCfg.outputLevel = 0;
789 state->m_qamRfAgcCfg.minOutputLevel = 6023;
790 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
791 state->m_qamRfAgcCfg.top = 0x2380;
792 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
793 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300794
795 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300796 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
797 state->m_qamIfAgcCfg.outputLevel = 0;
798 state->m_qamIfAgcCfg.minOutputLevel = 0;
799 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
800 state->m_qamIfAgcCfg.top = 0x0511;
801 state->m_qamIfAgcCfg.cutOffCurrent = 0;
802 state->m_qamIfAgcCfg.speed = 3;
803 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300804 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
805
Oliver Endrissebc7de22011-07-03 13:49:44 -0300806 state->m_qamPgaCfg = 140;
807 state->m_qamPreSawCfg.reference = 4;
808 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300809
810 state->m_OperationMode = OM_NONE;
811 state->m_DrxkState = DRXK_UNINITIALIZED;
812
813 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300814 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
815 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
816 state->m_enableParallel = true; /* If TRUE;
817 parallel out otherwise serial */
818 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
819 state->m_invertERR = false; /* If TRUE; invert ERR signal */
820 state->m_invertSTR = false; /* If TRUE; invert STR signals */
821 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
822 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300823 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300824 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300825 /* If TRUE; static MPEG clockrate will be used;
826 otherwise clockrate will adapt to the bitrate of the TS */
827
828 state->m_DVBTBitrate = ulDVBTBitrate;
829 state->m_DVBCBitrate = ulDVBCBitrate;
830
831 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
832 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
833
834 /* Maximum bitrate in b/s in case static clockrate is selected */
835 state->m_mpegTsStaticBitrate = 19392658;
836 state->m_disableTEIhandling = false;
837
838 if (ulInsertRSByte)
839 state->m_insertRSByte = true;
840
841 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
842 if (ulMpegLockTimeOut < 10000)
843 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
844 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
845 if (ulDemodLockTimeOut < 10000)
846 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
847
Oliver Endrissebc7de22011-07-03 13:49:44 -0300848 /* QAM defaults */
849 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300850 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300851 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
852 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300853
854 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
855 state->m_agcFastClipCtrlDelay = 0;
856
857 state->m_GPIOCfg = (ulGPIOCfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300858
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300859 state->m_bPowerDown = false;
860 state->m_currentPowerMode = DRX_POWER_DOWN;
861
862 state->m_enableParallel = (ulSerialMode == 0);
863
864 state->m_rfmirror = (ulRfMirror == 0);
865 state->m_IfAgcPol = false;
866 return 0;
867}
868
869static int DRXX_Open(struct drxk_state *state)
870{
871 int status = 0;
872 u32 jtag = 0;
873 u16 bid = 0;
874 u16 key = 0;
875
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300876 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300877 /* stop lock indicator process */
878 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
879 if (status < 0)
880 goto error;
881 /* Check device id */
882 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
883 if (status < 0)
884 goto error;
885 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
886 if (status < 0)
887 goto error;
888 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
889 if (status < 0)
890 goto error;
891 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
892 if (status < 0)
893 goto error;
894 status = write16(state, SIO_TOP_COMM_KEY__A, key);
895error:
896 if (status < 0)
897 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300898 return status;
899}
900
901static int GetDeviceCapabilities(struct drxk_state *state)
902{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300903 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300904 u32 sioTopJtagidLo = 0;
905 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300906 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300907
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300908 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300909
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300910 /* driver 0.9.0 */
911 /* stop lock indicator process */
912 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
913 if (status < 0)
914 goto error;
915 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
916 if (status < 0)
917 goto error;
918 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
919 if (status < 0)
920 goto error;
921 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
922 if (status < 0)
923 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300924
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300925 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
926 case 0:
927 /* ignore (bypass ?) */
928 break;
929 case 1:
930 /* 27 MHz */
931 state->m_oscClockFreq = 27000;
932 break;
933 case 2:
934 /* 20.25 MHz */
935 state->m_oscClockFreq = 20250;
936 break;
937 case 3:
938 /* 4 MHz */
939 state->m_oscClockFreq = 20250;
940 break;
941 default:
942 printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
943 return -EINVAL;
944 }
945 /*
946 Determine device capabilities
947 Based on pinning v14
948 */
949 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
950 if (status < 0)
951 goto error;
952 /* driver 0.9.0 */
953 switch ((sioTopJtagidLo >> 29) & 0xF) {
954 case 0:
955 state->m_deviceSpin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300956 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300957 break;
958 case 2:
959 state->m_deviceSpin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300960 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300961 break;
962 case 3:
963 state->m_deviceSpin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300964 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300965 break;
966 default:
967 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
968 status = -EINVAL;
969 printk(KERN_ERR "drxk: Spin unknown\n");
970 goto error2;
971 }
972 switch ((sioTopJtagidLo >> 12) & 0xFF) {
973 case 0x13:
974 /* typeId = DRX3913K_TYPE_ID */
975 state->m_hasLNA = false;
976 state->m_hasOOB = false;
977 state->m_hasATV = false;
978 state->m_hasAudio = false;
979 state->m_hasDVBT = true;
980 state->m_hasDVBC = true;
981 state->m_hasSAWSW = true;
982 state->m_hasGPIO2 = false;
983 state->m_hasGPIO1 = false;
984 state->m_hasIRQN = false;
985 break;
986 case 0x15:
987 /* typeId = DRX3915K_TYPE_ID */
988 state->m_hasLNA = false;
989 state->m_hasOOB = false;
990 state->m_hasATV = true;
991 state->m_hasAudio = false;
992 state->m_hasDVBT = true;
993 state->m_hasDVBC = false;
994 state->m_hasSAWSW = true;
995 state->m_hasGPIO2 = true;
996 state->m_hasGPIO1 = true;
997 state->m_hasIRQN = false;
998 break;
999 case 0x16:
1000 /* typeId = DRX3916K_TYPE_ID */
1001 state->m_hasLNA = false;
1002 state->m_hasOOB = false;
1003 state->m_hasATV = true;
1004 state->m_hasAudio = false;
1005 state->m_hasDVBT = true;
1006 state->m_hasDVBC = false;
1007 state->m_hasSAWSW = true;
1008 state->m_hasGPIO2 = true;
1009 state->m_hasGPIO1 = true;
1010 state->m_hasIRQN = false;
1011 break;
1012 case 0x18:
1013 /* typeId = DRX3918K_TYPE_ID */
1014 state->m_hasLNA = false;
1015 state->m_hasOOB = false;
1016 state->m_hasATV = true;
1017 state->m_hasAudio = true;
1018 state->m_hasDVBT = true;
1019 state->m_hasDVBC = false;
1020 state->m_hasSAWSW = true;
1021 state->m_hasGPIO2 = true;
1022 state->m_hasGPIO1 = true;
1023 state->m_hasIRQN = false;
1024 break;
1025 case 0x21:
1026 /* typeId = DRX3921K_TYPE_ID */
1027 state->m_hasLNA = false;
1028 state->m_hasOOB = false;
1029 state->m_hasATV = true;
1030 state->m_hasAudio = true;
1031 state->m_hasDVBT = true;
1032 state->m_hasDVBC = true;
1033 state->m_hasSAWSW = true;
1034 state->m_hasGPIO2 = true;
1035 state->m_hasGPIO1 = true;
1036 state->m_hasIRQN = false;
1037 break;
1038 case 0x23:
1039 /* typeId = DRX3923K_TYPE_ID */
1040 state->m_hasLNA = false;
1041 state->m_hasOOB = false;
1042 state->m_hasATV = true;
1043 state->m_hasAudio = true;
1044 state->m_hasDVBT = true;
1045 state->m_hasDVBC = true;
1046 state->m_hasSAWSW = true;
1047 state->m_hasGPIO2 = true;
1048 state->m_hasGPIO1 = true;
1049 state->m_hasIRQN = false;
1050 break;
1051 case 0x25:
1052 /* typeId = DRX3925K_TYPE_ID */
1053 state->m_hasLNA = false;
1054 state->m_hasOOB = false;
1055 state->m_hasATV = true;
1056 state->m_hasAudio = true;
1057 state->m_hasDVBT = true;
1058 state->m_hasDVBC = true;
1059 state->m_hasSAWSW = true;
1060 state->m_hasGPIO2 = true;
1061 state->m_hasGPIO1 = true;
1062 state->m_hasIRQN = false;
1063 break;
1064 case 0x26:
1065 /* typeId = DRX3926K_TYPE_ID */
1066 state->m_hasLNA = false;
1067 state->m_hasOOB = false;
1068 state->m_hasATV = true;
1069 state->m_hasAudio = false;
1070 state->m_hasDVBT = true;
1071 state->m_hasDVBC = true;
1072 state->m_hasSAWSW = true;
1073 state->m_hasGPIO2 = true;
1074 state->m_hasGPIO1 = true;
1075 state->m_hasIRQN = false;
1076 break;
1077 default:
1078 printk(KERN_ERR "drxk: DeviceID not supported = %02x\n",
1079 ((sioTopJtagidLo >> 12) & 0xFF));
1080 status = -EINVAL;
1081 goto error2;
1082 }
1083
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -03001084 printk(KERN_INFO
1085 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
1086 ((sioTopJtagidLo >> 12) & 0xFF), spin,
1087 state->m_oscClockFreq / 1000,
1088 state->m_oscClockFreq % 1000);
1089
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001090error:
1091 if (status < 0)
1092 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1093
1094error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001095 return status;
1096}
1097
1098static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1099{
1100 int status;
1101 bool powerdown_cmd;
1102
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001103 dprintk(1, "\n");
1104
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001105 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001106 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001107 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001108 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001109 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1110 msleep(1);
1111
1112 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001113 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1114 ((state->m_HICfgCtrl) &
1115 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1116 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001117 if (powerdown_cmd == false) {
1118 /* Wait until command rdy */
1119 u32 retryCount = 0;
1120 u16 waitCmd;
1121
1122 do {
1123 msleep(1);
1124 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001125 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1126 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001127 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1128 && (waitCmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001129 if (status < 0)
1130 goto error;
1131 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001132 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001133error:
1134 if (status < 0)
1135 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1136
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001137 return status;
1138}
1139
1140static int HI_CfgCommand(struct drxk_state *state)
1141{
1142 int status;
1143
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001144 dprintk(1, "\n");
1145
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001146 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001147
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001148 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1149 if (status < 0)
1150 goto error;
1151 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1152 if (status < 0)
1153 goto error;
1154 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1155 if (status < 0)
1156 goto error;
1157 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1158 if (status < 0)
1159 goto error;
1160 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1161 if (status < 0)
1162 goto error;
1163 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1164 if (status < 0)
1165 goto error;
1166 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1167 if (status < 0)
1168 goto error;
1169
1170 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1171error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001172 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001173 if (status < 0)
1174 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001175 return status;
1176}
1177
1178static int InitHI(struct drxk_state *state)
1179{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001180 dprintk(1, "\n");
1181
Oliver Endrissebc7de22011-07-03 13:49:44 -03001182 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001183 state->m_HICfgTimeout = 0x96FF;
1184 /* port/bridge/power down ctrl */
1185 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001186
Oliver Endrissebc7de22011-07-03 13:49:44 -03001187 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001188}
1189
1190static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1191{
1192 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001193 u16 sioPdrMclkCfg = 0;
1194 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001195
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001196 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001197
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001198 /* stop lock indicator process */
1199 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1200 if (status < 0)
1201 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001202
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001203 /* MPEG TS pad configuration */
1204 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1205 if (status < 0)
1206 goto error;
1207
1208 if (mpegEnable == false) {
1209 /* Set MPEG TS pads to inputmode */
1210 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1211 if (status < 0)
1212 goto error;
1213 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1214 if (status < 0)
1215 goto error;
1216 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1217 if (status < 0)
1218 goto error;
1219 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1220 if (status < 0)
1221 goto error;
1222 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1223 if (status < 0)
1224 goto error;
1225 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1226 if (status < 0)
1227 goto error;
1228 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1229 if (status < 0)
1230 goto error;
1231 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1232 if (status < 0)
1233 goto error;
1234 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1235 if (status < 0)
1236 goto error;
1237 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1238 if (status < 0)
1239 goto error;
1240 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1241 if (status < 0)
1242 goto error;
1243 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1244 if (status < 0)
1245 goto error;
1246 } else {
1247 /* Enable MPEG output */
1248 sioPdrMdxCfg =
1249 ((state->m_TSDataStrength <<
1250 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1251 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1252 SIO_PDR_MCLK_CFG_DRIVE__B) |
1253 0x0003);
1254
1255 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1256 if (status < 0)
1257 goto error;
1258 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
1259 if (status < 0)
1260 goto error;
1261 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
1262 if (status < 0)
1263 goto error;
1264 if (state->m_enableParallel == true) {
1265 /* paralel -> enable MD1 to MD7 */
1266 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001267 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001268 goto error;
1269 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001270 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001271 goto error;
1272 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001273 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001274 goto error;
1275 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001276 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001277 goto error;
1278 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001279 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001280 goto error;
1281 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1282 if (status < 0)
1283 goto error;
1284 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1285 if (status < 0)
1286 goto error;
1287 } else {
1288 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1289 SIO_PDR_MD0_CFG_DRIVE__B)
1290 | 0x0003);
1291 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001292 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001293 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001294 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001295 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001296 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001297 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001298 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001299 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001300 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001301 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001302 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001303 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001304 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001305 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001306 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001307 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001308 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001309 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001310 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001311 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001312 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001313 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001314 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001315 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001316 goto error;
1317 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001318 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001319 goto error;
1320 }
1321 /* Enable MB output over MPEG pads and ctl input */
1322 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1323 if (status < 0)
1324 goto error;
1325 /* Write nomagic word to enable pdr reg write */
1326 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1327error:
1328 if (status < 0)
1329 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001330 return status;
1331}
1332
1333static int MPEGTSDisable(struct drxk_state *state)
1334{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001335 dprintk(1, "\n");
1336
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001337 return MPEGTSConfigurePins(state, false);
1338}
1339
1340static int BLChainCmd(struct drxk_state *state,
1341 u16 romOffset, u16 nrOfElements, u32 timeOut)
1342{
1343 u16 blStatus = 0;
1344 int status;
1345 unsigned long end;
1346
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001347 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001348 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001349 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1350 if (status < 0)
1351 goto error;
1352 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1353 if (status < 0)
1354 goto error;
1355 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1356 if (status < 0)
1357 goto error;
1358 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1359 if (status < 0)
1360 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001361
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001362 end = jiffies + msecs_to_jiffies(timeOut);
1363 do {
1364 msleep(1);
1365 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1366 if (status < 0)
1367 goto error;
1368 } while ((blStatus == 0x1) &&
1369 ((time_is_after_jiffies(end))));
1370
1371 if (blStatus == 0x1) {
1372 printk(KERN_ERR "drxk: SIO not ready\n");
1373 status = -EINVAL;
1374 goto error2;
1375 }
1376error:
1377 if (status < 0)
1378 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1379error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001380 mutex_unlock(&state->mutex);
1381 return status;
1382}
1383
1384
1385static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001386 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001387{
1388 const u8 *pSrc = pMCImage;
1389 u16 Flags;
1390 u16 Drain;
1391 u32 Address;
1392 u16 nBlocks;
1393 u16 BlockSize;
1394 u16 BlockCRC;
1395 u32 offset = 0;
1396 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001397 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001398
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001399 dprintk(1, "\n");
1400
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001401 /* down the drain (we don care about MAGIC_WORD) */
1402 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001403 pSrc += sizeof(u16);
1404 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001405 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001406 pSrc += sizeof(u16);
1407 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001408
1409 for (i = 0; i < nBlocks; i += 1) {
1410 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001411 (pSrc[2] << 8) | pSrc[3];
1412 pSrc += sizeof(u32);
1413 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001414
1415 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001416 pSrc += sizeof(u16);
1417 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001418
1419 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001420 pSrc += sizeof(u16);
1421 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001422
1423 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001424 pSrc += sizeof(u16);
1425 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001426
1427 if (offset + BlockSize > Length) {
1428 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1429 return -EINVAL;
1430 }
1431
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001432 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001433 if (status < 0) {
1434 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001435 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001436 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001437 pSrc += BlockSize;
1438 offset += BlockSize;
1439 }
1440 return status;
1441}
1442
1443static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1444{
1445 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001446 u16 data = 0;
1447 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001448 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1449 unsigned long end;
1450
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001451 dprintk(1, "\n");
1452
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001453 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001454 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001455 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1456 }
1457
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001458 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1459 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001460 /* tokenring already has correct status */
1461 return status;
1462 }
1463 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001464 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001465
Oliver Endrissebc7de22011-07-03 13:49:44 -03001466 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001467 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001468 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001469 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001470 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001471 msleep(1);
1472 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001473 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001474 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001475 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001476 }
1477 return status;
1478}
1479
1480static int MPEGTSStop(struct drxk_state *state)
1481{
1482 int status = 0;
1483 u16 fecOcSncMode = 0;
1484 u16 fecOcIprMode = 0;
1485
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001486 dprintk(1, "\n");
1487
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001488 /* Gracefull shutdown (byte boundaries) */
1489 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1490 if (status < 0)
1491 goto error;
1492 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1493 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1494 if (status < 0)
1495 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001496
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001497 /* Suppress MCLK during absence of data */
1498 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1499 if (status < 0)
1500 goto error;
1501 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1502 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1503
1504error:
1505 if (status < 0)
1506 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1507
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001508 return status;
1509}
1510
1511static int scu_command(struct drxk_state *state,
1512 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001513 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001514{
1515#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1516#error DRXK register mapping no longer compatible with this routine!
1517#endif
1518 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001519 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001520 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001521 u8 buffer[34];
1522 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001523 const char *p;
1524 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001525
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001526 dprintk(1, "\n");
1527
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001528 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1529 ((resultLen > 0) && (result == NULL)))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001530 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001531
1532 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001533
1534 /* assume that the command register is ready
1535 since it is checked afterwards */
1536 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1537 buffer[cnt++] = (parameter[ii] & 0xFF);
1538 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1539 }
1540 buffer[cnt++] = (cmd & 0xFF);
1541 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1542
1543 write_block(state, SCU_RAM_PARAM_0__A -
1544 (parameterLen - 1), cnt, buffer);
1545 /* Wait until SCU has processed command */
1546 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001547 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001548 msleep(1);
1549 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1550 if (status < 0)
1551 goto error;
1552 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1553 if (curCmd != DRX_SCU_READY) {
1554 printk(KERN_ERR "drxk: SCU not ready\n");
1555 status = -EIO;
1556 goto error2;
1557 }
1558 /* read results */
1559 if ((resultLen > 0) && (result != NULL)) {
1560 s16 err;
1561 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001562
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001563 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1564 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001565 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001566 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001567 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001568
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001569 /* Check if an error was reported by SCU */
1570 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001571 if (err >= 0)
1572 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001573
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001574 /* check for the known error codes */
1575 switch (err) {
1576 case SCU_RESULT_UNKCMD:
1577 p = "SCU_RESULT_UNKCMD";
1578 break;
1579 case SCU_RESULT_UNKSTD:
1580 p = "SCU_RESULT_UNKSTD";
1581 break;
1582 case SCU_RESULT_SIZE:
1583 p = "SCU_RESULT_SIZE";
1584 break;
1585 case SCU_RESULT_INVPAR:
1586 p = "SCU_RESULT_INVPAR";
1587 break;
1588 default: /* Other negative values are errors */
1589 sprintf(errname, "ERROR: %d\n", err);
1590 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001591 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001592 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1593 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1594 status = -EINVAL;
1595 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001596 }
1597
1598error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001599 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001600 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001601error2:
1602 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001603 return status;
1604}
1605
1606static int SetIqmAf(struct drxk_state *state, bool active)
1607{
1608 u16 data = 0;
1609 int status;
1610
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001611 dprintk(1, "\n");
1612
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001613 /* Configure IQM */
1614 status = read16(state, IQM_AF_STDBY__A, &data);
1615 if (status < 0)
1616 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001617
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001618 if (!active) {
1619 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1620 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1621 | IQM_AF_STDBY_STDBY_PD_STANDBY
1622 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1623 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1624 } else {
1625 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1626 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1627 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1628 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1629 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1630 );
1631 }
1632 status = write16(state, IQM_AF_STDBY__A, data);
1633
1634error:
1635 if (status < 0)
1636 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001637 return status;
1638}
1639
Oliver Endrissebc7de22011-07-03 13:49:44 -03001640static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001641{
1642 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001643 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001644
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001645 dprintk(1, "\n");
1646
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001647 /* Check arguments */
1648 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001649 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001650
1651 switch (*mode) {
1652 case DRX_POWER_UP:
1653 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1654 break;
1655 case DRXK_POWER_DOWN_OFDM:
1656 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1657 break;
1658 case DRXK_POWER_DOWN_CORE:
1659 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1660 break;
1661 case DRXK_POWER_DOWN_PLL:
1662 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1663 break;
1664 case DRX_POWER_DOWN:
1665 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1666 break;
1667 default:
1668 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001669 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001670 break;
1671 }
1672
1673 /* If already in requested power mode, do nothing */
1674 if (state->m_currentPowerMode == *mode)
1675 return 0;
1676
1677 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001678 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001679 status = PowerUpDevice(state);
1680 if (status < 0)
1681 goto error;
1682 status = DVBTEnableOFDMTokenRing(state, true);
1683 if (status < 0)
1684 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001685 }
1686
1687 if (*mode == DRX_POWER_UP) {
1688 /* Restore analog & pin configuartion */
1689 } else {
1690 /* Power down to requested mode */
1691 /* Backup some register settings */
1692 /* Set pins with possible pull-ups connected
1693 to them in input mode */
1694 /* Analog power down */
1695 /* ADC power down */
1696 /* Power down device */
1697 /* stop all comm_exec */
1698 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001699 switch (state->m_OperationMode) {
1700 case OM_DVBT:
1701 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001702 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001703 goto error;
1704 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001705 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001706 goto error;
1707 break;
1708 case OM_QAM_ITU_A:
1709 case OM_QAM_ITU_C:
1710 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001711 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001712 goto error;
1713 status = PowerDownQAM(state);
1714 if (status < 0)
1715 goto error;
1716 break;
1717 default:
1718 break;
1719 }
1720 status = DVBTEnableOFDMTokenRing(state, false);
1721 if (status < 0)
1722 goto error;
1723 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1724 if (status < 0)
1725 goto error;
1726 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1727 if (status < 0)
1728 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001729
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001730 if (*mode != DRXK_POWER_DOWN_OFDM) {
1731 state->m_HICfgCtrl |=
1732 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1733 status = HI_CfgCommand(state);
1734 if (status < 0)
1735 goto error;
1736 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001737 }
1738 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001739
1740error:
1741 if (status < 0)
1742 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1743
Oliver Endrissebc7de22011-07-03 13:49:44 -03001744 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001745}
1746
1747static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1748{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001749 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001750 u16 cmdResult = 0;
1751 u16 data = 0;
1752 int status;
1753
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001754 dprintk(1, "\n");
1755
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001756 status = read16(state, SCU_COMM_EXEC__A, &data);
1757 if (status < 0)
1758 goto error;
1759 if (data == SCU_COMM_EXEC_ACTIVE) {
1760 /* Send OFDM stop command */
1761 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 -03001762 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001763 goto error;
1764 /* Send OFDM reset command */
1765 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1766 if (status < 0)
1767 goto error;
1768 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001769
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001770 /* Reset datapath for OFDM, processors first */
1771 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1772 if (status < 0)
1773 goto error;
1774 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1775 if (status < 0)
1776 goto error;
1777 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1778 if (status < 0)
1779 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001780
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001781 /* powerdown AFE */
1782 status = SetIqmAf(state, false);
1783 if (status < 0)
1784 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001785
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001786 /* powerdown to OFDM mode */
1787 if (setPowerMode) {
1788 status = CtrlPowerMode(state, &powerMode);
1789 if (status < 0)
1790 goto error;
1791 }
1792error:
1793 if (status < 0)
1794 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001795 return status;
1796}
1797
Oliver Endrissebc7de22011-07-03 13:49:44 -03001798static int SetOperationMode(struct drxk_state *state,
1799 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001800{
1801 int status = 0;
1802
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001803 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001804 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001805 Stop and power down previous standard
1806 TODO investigate total power down instead of partial
1807 power down depending on "previous" standard.
1808 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001809
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001810 /* disable HW lock indicator */
1811 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1812 if (status < 0)
1813 goto error;
1814
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001815 /* Device is already at the required mode */
1816 if (state->m_OperationMode == oMode)
1817 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001818
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001819 switch (state->m_OperationMode) {
1820 /* OM_NONE was added for start up */
1821 case OM_NONE:
1822 break;
1823 case OM_DVBT:
1824 status = MPEGTSStop(state);
1825 if (status < 0)
1826 goto error;
1827 status = PowerDownDVBT(state, true);
1828 if (status < 0)
1829 goto error;
1830 state->m_OperationMode = OM_NONE;
1831 break;
1832 case OM_QAM_ITU_A: /* fallthrough */
1833 case OM_QAM_ITU_C:
1834 status = MPEGTSStop(state);
1835 if (status < 0)
1836 goto error;
1837 status = PowerDownQAM(state);
1838 if (status < 0)
1839 goto error;
1840 state->m_OperationMode = OM_NONE;
1841 break;
1842 case OM_QAM_ITU_B:
1843 default:
1844 status = -EINVAL;
1845 goto error;
1846 }
1847
1848 /*
1849 Power up new standard
1850 */
1851 switch (oMode) {
1852 case OM_DVBT:
1853 state->m_OperationMode = oMode;
1854 status = SetDVBTStandard(state, oMode);
1855 if (status < 0)
1856 goto error;
1857 break;
1858 case OM_QAM_ITU_A: /* fallthrough */
1859 case OM_QAM_ITU_C:
1860 state->m_OperationMode = oMode;
1861 status = SetQAMStandard(state, oMode);
1862 if (status < 0)
1863 goto error;
1864 break;
1865 case OM_QAM_ITU_B:
1866 default:
1867 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001868 }
1869error:
1870 if (status < 0)
1871 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1872 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001873}
1874
1875static int Start(struct drxk_state *state, s32 offsetFreq,
1876 s32 IntermediateFrequency)
1877{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001878 int status = -EINVAL;
1879
1880 u16 IFreqkHz;
1881 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001882
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001883 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001884 if (state->m_DrxkState != DRXK_STOPPED &&
1885 state->m_DrxkState != DRXK_DTV_STARTED)
1886 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001887
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001888 state->m_bMirrorFreqSpect = (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001889
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001890 if (IntermediateFrequency < 0) {
1891 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1892 IntermediateFrequency = -IntermediateFrequency;
1893 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001894
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001895 switch (state->m_OperationMode) {
1896 case OM_QAM_ITU_A:
1897 case OM_QAM_ITU_C:
1898 IFreqkHz = (IntermediateFrequency / 1000);
1899 status = SetQAM(state, IFreqkHz, OffsetkHz);
1900 if (status < 0)
1901 goto error;
1902 state->m_DrxkState = DRXK_DTV_STARTED;
1903 break;
1904 case OM_DVBT:
1905 IFreqkHz = (IntermediateFrequency / 1000);
1906 status = MPEGTSStop(state);
1907 if (status < 0)
1908 goto error;
1909 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1910 if (status < 0)
1911 goto error;
1912 status = DVBTStart(state);
1913 if (status < 0)
1914 goto error;
1915 state->m_DrxkState = DRXK_DTV_STARTED;
1916 break;
1917 default:
1918 break;
1919 }
1920error:
1921 if (status < 0)
1922 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001923 return status;
1924}
1925
1926static int ShutDown(struct drxk_state *state)
1927{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001928 dprintk(1, "\n");
1929
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001930 MPEGTSStop(state);
1931 return 0;
1932}
1933
Oliver Endrissebc7de22011-07-03 13:49:44 -03001934static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1935 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001936{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001937 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001938
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001939 dprintk(1, "\n");
1940
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001941 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001942 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001943
1944 *pLockStatus = NOT_LOCKED;
1945
1946 /* define the SCU command code */
1947 switch (state->m_OperationMode) {
1948 case OM_QAM_ITU_A:
1949 case OM_QAM_ITU_B:
1950 case OM_QAM_ITU_C:
1951 status = GetQAMLockStatus(state, pLockStatus);
1952 break;
1953 case OM_DVBT:
1954 status = GetDVBTLockStatus(state, pLockStatus);
1955 break;
1956 default:
1957 break;
1958 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001959error:
1960 if (status < 0)
1961 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001962 return status;
1963}
1964
1965static int MPEGTSStart(struct drxk_state *state)
1966{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001967 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001968
1969 u16 fecOcSncMode = 0;
1970
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001971 /* Allow OC to sync again */
1972 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1973 if (status < 0)
1974 goto error;
1975 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1976 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1977 if (status < 0)
1978 goto error;
1979 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1980error:
1981 if (status < 0)
1982 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001983 return status;
1984}
1985
1986static int MPEGTSDtoInit(struct drxk_state *state)
1987{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001988 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001989
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001990 dprintk(1, "\n");
1991
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001992 /* Rate integration settings */
1993 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1994 if (status < 0)
1995 goto error;
1996 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1997 if (status < 0)
1998 goto error;
1999 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
2000 if (status < 0)
2001 goto error;
2002 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
2003 if (status < 0)
2004 goto error;
2005 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2006 if (status < 0)
2007 goto error;
2008 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2009 if (status < 0)
2010 goto error;
2011 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2012 if (status < 0)
2013 goto error;
2014 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2015 if (status < 0)
2016 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002017
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002018 /* Additional configuration */
2019 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2020 if (status < 0)
2021 goto error;
2022 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2023 if (status < 0)
2024 goto error;
2025 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2026error:
2027 if (status < 0)
2028 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2029
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002030 return status;
2031}
2032
Oliver Endrissebc7de22011-07-03 13:49:44 -03002033static int MPEGTSDtoSetup(struct drxk_state *state,
2034 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002035{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002036 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002037
Oliver Endrissebc7de22011-07-03 13:49:44 -03002038 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2039 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2040 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2041 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2042 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2043 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2044 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002045 u16 fecOcTmdMode = 0;
2046 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002047 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002048 bool staticCLK = false;
2049
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002050 dprintk(1, "\n");
2051
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002052 /* Check insertion of the Reed-Solomon parity bytes */
2053 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2054 if (status < 0)
2055 goto error;
2056 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2057 if (status < 0)
2058 goto error;
2059 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2060 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2061 if (state->m_insertRSByte == true) {
2062 /* enable parity symbol forward */
2063 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2064 /* MVAL disable during parity bytes */
2065 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2066 /* TS burst length to 204 */
2067 fecOcDtoBurstLen = 204;
2068 }
2069
2070 /* Check serial or parrallel output */
2071 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2072 if (state->m_enableParallel == false) {
2073 /* MPEG data output is serial -> set ipr_mode[0] */
2074 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2075 }
2076
2077 switch (oMode) {
2078 case OM_DVBT:
2079 maxBitRate = state->m_DVBTBitrate;
2080 fecOcTmdMode = 3;
2081 fecOcRcnCtlRate = 0xC00000;
2082 staticCLK = state->m_DVBTStaticCLK;
2083 break;
2084 case OM_QAM_ITU_A: /* fallthrough */
2085 case OM_QAM_ITU_C:
2086 fecOcTmdMode = 0x0004;
2087 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2088 maxBitRate = state->m_DVBCBitrate;
2089 staticCLK = state->m_DVBCStaticCLK;
2090 break;
2091 default:
2092 status = -EINVAL;
2093 } /* switch (standard) */
2094 if (status < 0)
2095 goto error;
2096
2097 /* Configure DTO's */
2098 if (staticCLK) {
2099 u32 bitRate = 0;
2100
2101 /* Rational DTO for MCLK source (static MCLK rate),
2102 Dynamic DTO for optimal grouping
2103 (avoid intra-packet gaps),
2104 DTO offset enable to sync TS burst with MSTRT */
2105 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2106 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2107 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2108 FEC_OC_FCT_MODE_VIRT_ENA__M);
2109
2110 /* Check user defined bitrate */
2111 bitRate = maxBitRate;
2112 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2113 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002114 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002115 /* Rational DTO period:
2116 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002117
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002118 Result should be floored,
2119 to make sure >= requested bitrate
2120 */
2121 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2122 * 1000) / bitRate);
2123 if (fecOcDtoPeriod <= 2)
2124 fecOcDtoPeriod = 0;
2125 else
2126 fecOcDtoPeriod -= 2;
2127 fecOcTmdIntUpdRate = 8;
2128 } else {
2129 /* (commonAttr->staticCLK == false) => dynamic mode */
2130 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2131 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2132 fecOcTmdIntUpdRate = 5;
2133 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002134
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002135 /* Write appropriate registers with requested configuration */
2136 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2137 if (status < 0)
2138 goto error;
2139 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2140 if (status < 0)
2141 goto error;
2142 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2143 if (status < 0)
2144 goto error;
2145 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2146 if (status < 0)
2147 goto error;
2148 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2149 if (status < 0)
2150 goto error;
2151 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2152 if (status < 0)
2153 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002154
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002155 /* Rate integration settings */
2156 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2157 if (status < 0)
2158 goto error;
2159 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2160 if (status < 0)
2161 goto error;
2162 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2163error:
2164 if (status < 0)
2165 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002166 return status;
2167}
2168
2169static int MPEGTSConfigurePolarity(struct drxk_state *state)
2170{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002171 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002172
2173 /* Data mask for the output data byte */
2174 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002175 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2176 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2177 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2178 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002179
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002180 dprintk(1, "\n");
2181
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002182 /* Control selective inversion of output bits */
2183 fecOcRegIprInvert &= (~(InvertDataMask));
2184 if (state->m_invertDATA == true)
2185 fecOcRegIprInvert |= InvertDataMask;
2186 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2187 if (state->m_invertERR == true)
2188 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2189 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2190 if (state->m_invertSTR == true)
2191 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2192 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2193 if (state->m_invertVAL == true)
2194 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2195 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2196 if (state->m_invertCLK == true)
2197 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002198
2199 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002200}
2201
2202#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2203
2204static int SetAgcRf(struct drxk_state *state,
2205 struct SCfgAgc *pAgcCfg, bool isDTV)
2206{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002207 int status = -EINVAL;
2208 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002209 struct SCfgAgc *pIfAgcSettings;
2210
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002211 dprintk(1, "\n");
2212
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002213 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002214 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002215
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002216 switch (pAgcCfg->ctrlMode) {
2217 case DRXK_AGC_CTRL_AUTO:
2218 /* Enable RF AGC DAC */
2219 status = read16(state, IQM_AF_STDBY__A, &data);
2220 if (status < 0)
2221 goto error;
2222 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2223 status = write16(state, IQM_AF_STDBY__A, data);
2224 if (status < 0)
2225 goto error;
2226 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2227 if (status < 0)
2228 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002229
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002230 /* Enable SCU RF AGC loop */
2231 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002232
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002233 /* Polarity */
2234 if (state->m_RfAgcPol)
2235 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2236 else
2237 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2238 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2239 if (status < 0)
2240 goto error;
2241
2242 /* Set speed (using complementary reduction value) */
2243 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2244 if (status < 0)
2245 goto error;
2246
2247 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2248 data |= (~(pAgcCfg->speed <<
2249 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2250 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2251
2252 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2253 if (status < 0)
2254 goto error;
2255
2256 if (IsDVBT(state))
2257 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2258 else if (IsQAM(state))
2259 pIfAgcSettings = &state->m_qamIfAgcCfg;
2260 else
2261 pIfAgcSettings = &state->m_atvIfAgcCfg;
2262 if (pIfAgcSettings == NULL) {
2263 status = -EINVAL;
2264 goto error;
2265 }
2266
2267 /* Set TOP, only if IF-AGC is in AUTO mode */
2268 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2269 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002270 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002271 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002272
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002273 /* Cut-Off current */
2274 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2275 if (status < 0)
2276 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002277
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002278 /* Max. output level */
2279 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2280 if (status < 0)
2281 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002282
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002283 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002284
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002285 case DRXK_AGC_CTRL_USER:
2286 /* Enable RF AGC DAC */
2287 status = read16(state, IQM_AF_STDBY__A, &data);
2288 if (status < 0)
2289 goto error;
2290 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2291 status = write16(state, IQM_AF_STDBY__A, data);
2292 if (status < 0)
2293 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002294
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002295 /* Disable SCU RF AGC loop */
2296 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2297 if (status < 0)
2298 goto error;
2299 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2300 if (state->m_RfAgcPol)
2301 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2302 else
2303 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2304 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2305 if (status < 0)
2306 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002307
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002308 /* SCU c.o.c. to 0, enabling full control range */
2309 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2310 if (status < 0)
2311 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002312
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002313 /* Write value to output pin */
2314 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2315 if (status < 0)
2316 goto error;
2317 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002318
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002319 case DRXK_AGC_CTRL_OFF:
2320 /* Disable RF AGC DAC */
2321 status = read16(state, IQM_AF_STDBY__A, &data);
2322 if (status < 0)
2323 goto error;
2324 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2325 status = write16(state, IQM_AF_STDBY__A, data);
2326 if (status < 0)
2327 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002328
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002329 /* Disable SCU RF AGC loop */
2330 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2331 if (status < 0)
2332 goto error;
2333 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2334 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2335 if (status < 0)
2336 goto error;
2337 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002338
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002339 default:
2340 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002341
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002342 }
2343error:
2344 if (status < 0)
2345 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002346 return status;
2347}
2348
2349#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2350
Oliver Endrissebc7de22011-07-03 13:49:44 -03002351static int SetAgcIf(struct drxk_state *state,
2352 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002353{
2354 u16 data = 0;
2355 int status = 0;
2356 struct SCfgAgc *pRfAgcSettings;
2357
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002358 dprintk(1, "\n");
2359
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002360 switch (pAgcCfg->ctrlMode) {
2361 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002362
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002363 /* Enable IF AGC DAC */
2364 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002365 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002366 goto error;
2367 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2368 status = write16(state, IQM_AF_STDBY__A, data);
2369 if (status < 0)
2370 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002371
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002372 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2373 if (status < 0)
2374 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002375
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002376 /* Enable SCU IF AGC loop */
2377 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2378
2379 /* Polarity */
2380 if (state->m_IfAgcPol)
2381 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2382 else
2383 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2384 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2385 if (status < 0)
2386 goto error;
2387
2388 /* Set speed (using complementary reduction value) */
2389 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2390 if (status < 0)
2391 goto error;
2392 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2393 data |= (~(pAgcCfg->speed <<
2394 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2395 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2396
2397 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2398 if (status < 0)
2399 goto error;
2400
2401 if (IsQAM(state))
2402 pRfAgcSettings = &state->m_qamRfAgcCfg;
2403 else
2404 pRfAgcSettings = &state->m_atvRfAgcCfg;
2405 if (pRfAgcSettings == NULL)
2406 return -1;
2407 /* Restore TOP */
2408 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2409 if (status < 0)
2410 goto error;
2411 break;
2412
2413 case DRXK_AGC_CTRL_USER:
2414
2415 /* Enable IF AGC DAC */
2416 status = read16(state, IQM_AF_STDBY__A, &data);
2417 if (status < 0)
2418 goto error;
2419 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2420 status = write16(state, IQM_AF_STDBY__A, data);
2421 if (status < 0)
2422 goto error;
2423
2424 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2425 if (status < 0)
2426 goto error;
2427
2428 /* Disable SCU IF AGC loop */
2429 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2430
2431 /* Polarity */
2432 if (state->m_IfAgcPol)
2433 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2434 else
2435 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2436 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2437 if (status < 0)
2438 goto error;
2439
2440 /* Write value to output pin */
2441 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2442 if (status < 0)
2443 goto error;
2444 break;
2445
2446 case DRXK_AGC_CTRL_OFF:
2447
2448 /* Disable If AGC DAC */
2449 status = read16(state, IQM_AF_STDBY__A, &data);
2450 if (status < 0)
2451 goto error;
2452 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2453 status = write16(state, IQM_AF_STDBY__A, data);
2454 if (status < 0)
2455 goto error;
2456
2457 /* Disable SCU IF AGC loop */
2458 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2459 if (status < 0)
2460 goto error;
2461 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2462 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2463 if (status < 0)
2464 goto error;
2465 break;
2466 } /* switch (agcSettingsIf->ctrlMode) */
2467
2468 /* always set the top to support
2469 configurations without if-loop */
2470 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2471error:
2472 if (status < 0)
2473 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002474 return status;
2475}
2476
2477static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2478{
2479 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002480 int status;
2481 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002482
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002483 dprintk(1, "\n");
2484
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002485 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2486 if (status < 0) {
2487 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2488 return status;
2489 }
2490
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002491 *pValue = 0;
2492
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002493 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2494 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2495 if (Level < 14000)
2496 *pValue = (14000 - Level) / 4;
2497 else
2498 *pValue = 0;
2499
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002500 return status;
2501}
2502
Oliver Endrissebc7de22011-07-03 13:49:44 -03002503static int GetQAMSignalToNoise(struct drxk_state *state,
2504 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002505{
2506 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002507 u16 qamSlErrPower = 0; /* accum. error between
2508 raw and sliced symbols */
2509 u32 qamSlSigPower = 0; /* used for MER, depends of
2510 QAM constellation */
2511 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002512
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002513 dprintk(1, "\n");
2514
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002515 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002516
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002517 /* get the register value needed for MER */
2518 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2519 if (status < 0) {
2520 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2521 return -EINVAL;
2522 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002523
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002524 switch (state->param.u.qam.modulation) {
2525 case QAM_16:
2526 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2527 break;
2528 case QAM_32:
2529 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2530 break;
2531 case QAM_64:
2532 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2533 break;
2534 case QAM_128:
2535 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2536 break;
2537 default:
2538 case QAM_256:
2539 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2540 break;
2541 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002542
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002543 if (qamSlErrPower > 0) {
2544 qamSlMer = Log10Times100(qamSlSigPower) -
2545 Log10Times100((u32) qamSlErrPower);
2546 }
2547 *pSignalToNoise = qamSlMer;
2548
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002549 return status;
2550}
2551
Oliver Endrissebc7de22011-07-03 13:49:44 -03002552static int GetDVBTSignalToNoise(struct drxk_state *state,
2553 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002554{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002555 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002556 u16 regData = 0;
2557 u32 EqRegTdSqrErrI = 0;
2558 u32 EqRegTdSqrErrQ = 0;
2559 u16 EqRegTdSqrErrExp = 0;
2560 u16 EqRegTdTpsPwrOfs = 0;
2561 u16 EqRegTdReqSmbCnt = 0;
2562 u32 tpsCnt = 0;
2563 u32 SqrErrIQ = 0;
2564 u32 a = 0;
2565 u32 b = 0;
2566 u32 c = 0;
2567 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002568 u16 transmissionParams = 0;
2569
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002570 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002571
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002572 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2573 if (status < 0)
2574 goto error;
2575 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2576 if (status < 0)
2577 goto error;
2578 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2579 if (status < 0)
2580 goto error;
2581 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2582 if (status < 0)
2583 goto error;
2584 /* Extend SQR_ERR_I operational range */
2585 EqRegTdSqrErrI = (u32) regData;
2586 if ((EqRegTdSqrErrExp > 11) &&
2587 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2588 EqRegTdSqrErrI += 0x00010000UL;
2589 }
2590 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2591 if (status < 0)
2592 goto error;
2593 /* Extend SQR_ERR_Q operational range */
2594 EqRegTdSqrErrQ = (u32) regData;
2595 if ((EqRegTdSqrErrExp > 11) &&
2596 (EqRegTdSqrErrQ < 0x00000FFFUL))
2597 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002598
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002599 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2600 if (status < 0)
2601 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002602
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002603 /* Check input data for MER */
2604
2605 /* MER calculation (in 0.1 dB) without math.h */
2606 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2607 iMER = 0;
2608 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2609 /* No error at all, this must be the HW reset value
2610 * Apparently no first measurement yet
2611 * Set MER to 0.0 */
2612 iMER = 0;
2613 } else {
2614 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2615 EqRegTdSqrErrExp;
2616 if ((transmissionParams &
2617 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2618 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2619 tpsCnt = 17;
2620 else
2621 tpsCnt = 68;
2622
2623 /* IMER = 100 * log10 (x)
2624 where x = (EqRegTdTpsPwrOfs^2 *
2625 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2626
2627 => IMER = a + b -c
2628 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2629 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2630 c = 100 * log10 (SqrErrIQ)
2631 */
2632
2633 /* log(x) x = 9bits * 9bits->18 bits */
2634 a = Log10Times100(EqRegTdTpsPwrOfs *
2635 EqRegTdTpsPwrOfs);
2636 /* log(x) x = 16bits * 7bits->23 bits */
2637 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2638 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2639 c = Log10Times100(SqrErrIQ);
2640
2641 iMER = a + b;
2642 /* No negative MER, clip to zero */
2643 if (iMER > c)
2644 iMER -= c;
2645 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002646 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002647 }
2648 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002649
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002650error:
2651 if (status < 0)
2652 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002653 return status;
2654}
2655
2656static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2657{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002658 dprintk(1, "\n");
2659
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002660 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002661 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002662 case OM_DVBT:
2663 return GetDVBTSignalToNoise(state, pSignalToNoise);
2664 case OM_QAM_ITU_A:
2665 case OM_QAM_ITU_C:
2666 return GetQAMSignalToNoise(state, pSignalToNoise);
2667 default:
2668 break;
2669 }
2670 return 0;
2671}
2672
2673#if 0
2674static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2675{
2676 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2677 int status = 0;
2678
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002679 dprintk(1, "\n");
2680
Oliver Endrissebc7de22011-07-03 13:49:44 -03002681 static s32 QE_SN[] = {
2682 51, /* QPSK 1/2 */
2683 69, /* QPSK 2/3 */
2684 79, /* QPSK 3/4 */
2685 89, /* QPSK 5/6 */
2686 97, /* QPSK 7/8 */
2687 108, /* 16-QAM 1/2 */
2688 131, /* 16-QAM 2/3 */
2689 146, /* 16-QAM 3/4 */
2690 156, /* 16-QAM 5/6 */
2691 160, /* 16-QAM 7/8 */
2692 165, /* 64-QAM 1/2 */
2693 187, /* 64-QAM 2/3 */
2694 202, /* 64-QAM 3/4 */
2695 216, /* 64-QAM 5/6 */
2696 225, /* 64-QAM 7/8 */
2697 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002698
2699 *pQuality = 0;
2700
2701 do {
2702 s32 SignalToNoise = 0;
2703 u16 Constellation = 0;
2704 u16 CodeRate = 0;
2705 u32 SignalToNoiseRel;
2706 u32 BERQuality;
2707
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002708 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2709 if (status < 0)
2710 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002711 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002712 if (status < 0)
2713 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002714 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2715
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002716 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002717 if (status < 0)
2718 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002719 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2720
2721 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2722 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2723 break;
2724 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002725 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002726 BERQuality = 100;
2727
Oliver Endrissebc7de22011-07-03 13:49:44 -03002728 if (SignalToNoiseRel < -70)
2729 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002730 else if (SignalToNoiseRel < 30)
2731 *pQuality = ((SignalToNoiseRel + 70) *
2732 BERQuality) / 100;
2733 else
2734 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002735 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002736 return 0;
2737};
2738
Oliver Endrissebc7de22011-07-03 13:49:44 -03002739static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002740{
2741 int status = 0;
2742 *pQuality = 0;
2743
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002744 dprintk(1, "\n");
2745
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002746 do {
2747 u32 SignalToNoise = 0;
2748 u32 BERQuality = 100;
2749 u32 SignalToNoiseRel = 0;
2750
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002751 status = GetQAMSignalToNoise(state, &SignalToNoise);
2752 if (status < 0)
2753 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002754
Oliver Endrissebc7de22011-07-03 13:49:44 -03002755 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002756 case QAM_16:
2757 SignalToNoiseRel = SignalToNoise - 200;
2758 break;
2759 case QAM_32:
2760 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002761 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002762 case QAM_64:
2763 SignalToNoiseRel = SignalToNoise - 260;
2764 break;
2765 case QAM_128:
2766 SignalToNoiseRel = SignalToNoise - 290;
2767 break;
2768 default:
2769 case QAM_256:
2770 SignalToNoiseRel = SignalToNoise - 320;
2771 break;
2772 }
2773
2774 if (SignalToNoiseRel < -70)
2775 *pQuality = 0;
2776 else if (SignalToNoiseRel < 30)
2777 *pQuality = ((SignalToNoiseRel + 70) *
2778 BERQuality) / 100;
2779 else
2780 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002781 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002782
2783 return status;
2784}
2785
2786static int GetQuality(struct drxk_state *state, s32 *pQuality)
2787{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002788 dprintk(1, "\n");
2789
Oliver Endrissebc7de22011-07-03 13:49:44 -03002790 switch (state->m_OperationMode) {
2791 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002792 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002793 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002794 return GetDVBCQuality(state, pQuality);
2795 default:
2796 break;
2797 }
2798
2799 return 0;
2800}
2801#endif
2802
2803/* Free data ram in SIO HI */
2804#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2805#define SIO_HI_RA_RAM_USR_END__A 0x420060
2806
2807#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2808#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2809#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2810#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2811
2812#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2813#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2814#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2815
2816static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2817{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002818 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002819
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002820 dprintk(1, "\n");
2821
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002822 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002823 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002824 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002825 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002826
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002827 if (state->no_i2c_bridge)
2828 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002829
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002830 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2831 if (status < 0)
2832 goto error;
2833 if (bEnableBridge) {
2834 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002835 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002836 goto error;
2837 } else {
2838 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2839 if (status < 0)
2840 goto error;
2841 }
2842
2843 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2844
2845error:
2846 if (status < 0)
2847 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002848 return status;
2849}
2850
Oliver Endrissebc7de22011-07-03 13:49:44 -03002851static int SetPreSaw(struct drxk_state *state,
2852 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002853{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002854 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002855
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002856 dprintk(1, "\n");
2857
Oliver Endrissebc7de22011-07-03 13:49:44 -03002858 if ((pPreSawCfg == NULL)
2859 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002860 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002861
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002862 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002863error:
2864 if (status < 0)
2865 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002866 return status;
2867}
2868
2869static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002870 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002871{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002872 u16 blStatus = 0;
2873 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2874 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2875 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002876 unsigned long end;
2877
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002878 dprintk(1, "\n");
2879
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002880 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002881 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2882 if (status < 0)
2883 goto error;
2884 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2885 if (status < 0)
2886 goto error;
2887 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2888 if (status < 0)
2889 goto error;
2890 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2891 if (status < 0)
2892 goto error;
2893 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2894 if (status < 0)
2895 goto error;
2896 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2897 if (status < 0)
2898 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002899
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002900 end = jiffies + msecs_to_jiffies(timeOut);
2901 do {
2902 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2903 if (status < 0)
2904 goto error;
2905 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2906 if (blStatus == 0x1) {
2907 printk(KERN_ERR "drxk: SIO not ready\n");
2908 status = -EINVAL;
2909 goto error2;
2910 }
2911error:
2912 if (status < 0)
2913 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2914error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002915 mutex_unlock(&state->mutex);
2916 return status;
2917
2918}
2919
Oliver Endrissebc7de22011-07-03 13:49:44 -03002920static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002921{
2922 u16 data = 0;
2923 int status;
2924
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002925 dprintk(1, "\n");
2926
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002927 /* Start measurement */
2928 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2929 if (status < 0)
2930 goto error;
2931 status = write16(state, IQM_AF_START_LOCK__A, 1);
2932 if (status < 0)
2933 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002934
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002935 *count = 0;
2936 status = read16(state, IQM_AF_PHASE0__A, &data);
2937 if (status < 0)
2938 goto error;
2939 if (data == 127)
2940 *count = *count + 1;
2941 status = read16(state, IQM_AF_PHASE1__A, &data);
2942 if (status < 0)
2943 goto error;
2944 if (data == 127)
2945 *count = *count + 1;
2946 status = read16(state, IQM_AF_PHASE2__A, &data);
2947 if (status < 0)
2948 goto error;
2949 if (data == 127)
2950 *count = *count + 1;
2951
2952error:
2953 if (status < 0)
2954 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002955 return status;
2956}
2957
2958static int ADCSynchronization(struct drxk_state *state)
2959{
2960 u16 count = 0;
2961 int status;
2962
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002963 dprintk(1, "\n");
2964
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002965 status = ADCSyncMeasurement(state, &count);
2966 if (status < 0)
2967 goto error;
2968
2969 if (count == 1) {
2970 /* Try sampling on a diffrent edge */
2971 u16 clkNeg = 0;
2972
2973 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2974 if (status < 0)
2975 goto error;
2976 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2977 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2978 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2979 clkNeg |=
2980 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2981 } else {
2982 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2983 clkNeg |=
2984 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2985 }
2986 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2987 if (status < 0)
2988 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002989 status = ADCSyncMeasurement(state, &count);
2990 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002991 goto error;
2992 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002993
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002994 if (count < 2)
2995 status = -EINVAL;
2996error:
2997 if (status < 0)
2998 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002999 return status;
3000}
3001
3002static int SetFrequencyShifter(struct drxk_state *state,
3003 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003004 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003005{
3006 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003007 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003008 u32 fmFrequencyShift = 0;
3009 bool tunerMirror = !state->m_bMirrorFreqSpect;
3010 u32 adcFreq;
3011 bool adcFlip;
3012 int status;
3013 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003014 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003015 u32 frequencyShift;
3016 bool imageToSelect;
3017
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003018 dprintk(1, "\n");
3019
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003020 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003021 Program frequency shifter
3022 No need to account for mirroring on RF
3023 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003024 if (isDTV) {
3025 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3026 (state->m_OperationMode == OM_QAM_ITU_C) ||
3027 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003028 selectPosImage = true;
3029 else
3030 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003031 }
3032 if (tunerMirror)
3033 /* tuner doesn't mirror */
3034 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003035 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003036 else
3037 /* tuner mirrors */
3038 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003039 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003040 if (ifFreqActual > samplingFrequency / 2) {
3041 /* adc mirrors */
3042 adcFreq = samplingFrequency - ifFreqActual;
3043 adcFlip = true;
3044 } else {
3045 /* adc doesn't mirror */
3046 adcFreq = ifFreqActual;
3047 adcFlip = false;
3048 }
3049
3050 frequencyShift = adcFreq;
3051 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003052 adcFlip ^ selectPosImage;
3053 state->m_IqmFsRateOfs =
3054 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003055
3056 if (imageToSelect)
3057 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3058
3059 /* Program frequency shifter with tuner offset compensation */
3060 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003061 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3062 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003063 if (status < 0)
3064 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003065 return status;
3066}
3067
3068static int InitAGC(struct drxk_state *state, bool isDTV)
3069{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003070 u16 ingainTgt = 0;
3071 u16 ingainTgtMin = 0;
3072 u16 ingainTgtMax = 0;
3073 u16 clpCyclen = 0;
3074 u16 clpSumMin = 0;
3075 u16 clpDirTo = 0;
3076 u16 snsSumMin = 0;
3077 u16 snsSumMax = 0;
3078 u16 clpSumMax = 0;
3079 u16 snsDirTo = 0;
3080 u16 kiInnergainMin = 0;
3081 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003082 u16 ifIaccuHiTgtMin = 0;
3083 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003084 u16 data = 0;
3085 u16 fastClpCtrlDelay = 0;
3086 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003087 int status = 0;
3088
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003089 dprintk(1, "\n");
3090
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003091 /* Common settings */
3092 snsSumMax = 1023;
3093 ifIaccuHiTgtMin = 2047;
3094 clpCyclen = 500;
3095 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003096
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003097 /* AGCInit() not available for DVBT; init done in microcode */
3098 if (!IsQAM(state)) {
3099 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3100 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003101 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003102
3103 /* FIXME: Analog TV AGC require different settings */
3104
3105 /* Standard specific settings */
3106 clpSumMin = 8;
3107 clpDirTo = (u16) -9;
3108 clpCtrlMode = 0;
3109 snsSumMin = 8;
3110 snsDirTo = (u16) -9;
3111 kiInnergainMin = (u16) -1030;
3112 ifIaccuHiTgtMax = 0x2380;
3113 ifIaccuHiTgt = 0x2380;
3114 ingainTgtMin = 0x0511;
3115 ingainTgt = 0x0511;
3116 ingainTgtMax = 5119;
3117 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3118
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003119 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3120 if (status < 0)
3121 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003122
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003123 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3124 if (status < 0)
3125 goto error;
3126 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3127 if (status < 0)
3128 goto error;
3129 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3130 if (status < 0)
3131 goto error;
3132 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3133 if (status < 0)
3134 goto error;
3135 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3136 if (status < 0)
3137 goto error;
3138 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3139 if (status < 0)
3140 goto error;
3141 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3142 if (status < 0)
3143 goto error;
3144 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3145 if (status < 0)
3146 goto error;
3147 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3148 if (status < 0)
3149 goto error;
3150 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3151 if (status < 0)
3152 goto error;
3153 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3154 if (status < 0)
3155 goto error;
3156 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3157 if (status < 0)
3158 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003159
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003160 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3161 if (status < 0)
3162 goto error;
3163 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3164 if (status < 0)
3165 goto error;
3166 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3167 if (status < 0)
3168 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003169
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003170 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3171 if (status < 0)
3172 goto error;
3173 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3174 if (status < 0)
3175 goto error;
3176 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3177 if (status < 0)
3178 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003179
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003180 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3181 if (status < 0)
3182 goto error;
3183 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3184 if (status < 0)
3185 goto error;
3186 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3187 if (status < 0)
3188 goto error;
3189 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3190 if (status < 0)
3191 goto error;
3192 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3193 if (status < 0)
3194 goto error;
3195 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3196 if (status < 0)
3197 goto error;
3198 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3199 if (status < 0)
3200 goto error;
3201 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3202 if (status < 0)
3203 goto error;
3204 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3205 if (status < 0)
3206 goto error;
3207 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3208 if (status < 0)
3209 goto error;
3210 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3211 if (status < 0)
3212 goto error;
3213 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3214 if (status < 0)
3215 goto error;
3216 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3217 if (status < 0)
3218 goto error;
3219 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3220 if (status < 0)
3221 goto error;
3222 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3223 if (status < 0)
3224 goto error;
3225 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3226 if (status < 0)
3227 goto error;
3228 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3229 if (status < 0)
3230 goto error;
3231 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3232 if (status < 0)
3233 goto error;
3234 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3235 if (status < 0)
3236 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003237
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003238 /* Initialize inner-loop KI gain factors */
3239 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3240 if (status < 0)
3241 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003242
3243 data = 0x0657;
3244 data &= ~SCU_RAM_AGC_KI_RF__M;
3245 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3246 data &= ~SCU_RAM_AGC_KI_IF__M;
3247 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3248
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003249 status = write16(state, SCU_RAM_AGC_KI__A, data);
3250error:
3251 if (status < 0)
3252 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003253 return status;
3254}
3255
Oliver Endrissebc7de22011-07-03 13:49:44 -03003256static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003257{
3258 int status;
3259
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003260 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003261 if (packetErr == NULL)
3262 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3263 else
3264 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3265 if (status < 0)
3266 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003267 return status;
3268}
3269
3270static int DVBTScCommand(struct drxk_state *state,
3271 u16 cmd, u16 subcmd,
3272 u16 param0, u16 param1, u16 param2,
3273 u16 param3, u16 param4)
3274{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003275 u16 curCmd = 0;
3276 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003277 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003278 u16 scExec = 0;
3279 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003280
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003281 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003282 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003283 if (scExec != 1) {
3284 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003285 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003286 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003287 if (status < 0)
3288 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003289
3290 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003291 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003292 do {
3293 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003294 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003295 retryCnt++;
3296 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003297 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3298 goto error;
3299
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003300 /* Write sub-command */
3301 switch (cmd) {
3302 /* All commands using sub-cmd */
3303 case OFDM_SC_RA_RAM_CMD_PROC_START:
3304 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3305 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003306 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3307 if (status < 0)
3308 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003309 break;
3310 default:
3311 /* Do nothing */
3312 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003313 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003314
3315 /* Write needed parameters and the command */
3316 switch (cmd) {
3317 /* All commands using 5 parameters */
3318 /* All commands using 4 parameters */
3319 /* All commands using 3 parameters */
3320 /* All commands using 2 parameters */
3321 case OFDM_SC_RA_RAM_CMD_PROC_START:
3322 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3323 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003324 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003325 /* All commands using 1 parameters */
3326 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3327 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003328 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003329 /* All commands using 0 parameters */
3330 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3331 case OFDM_SC_RA_RAM_CMD_NULL:
3332 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003333 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003334 break;
3335 default:
3336 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003337 status = -EINVAL;
3338 }
3339 if (status < 0)
3340 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003341
3342 /* Wait until sc is ready processing command */
3343 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003344 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003345 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003346 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003347 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003348 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003349 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3350 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003351
3352 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003353 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003354 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003355 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003356 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003357 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003358 if (status < 0)
3359 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003360
3361 /* Retreive results parameters from SC */
3362 switch (cmd) {
3363 /* All commands yielding 5 results */
3364 /* All commands yielding 4 results */
3365 /* All commands yielding 3 results */
3366 /* All commands yielding 2 results */
3367 /* All commands yielding 1 result */
3368 case OFDM_SC_RA_RAM_CMD_USER_IO:
3369 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003370 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003371 /* All commands yielding 0 results */
3372 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3373 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3374 case OFDM_SC_RA_RAM_CMD_PROC_START:
3375 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3376 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3377 case OFDM_SC_RA_RAM_CMD_NULL:
3378 break;
3379 default:
3380 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003381 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003382 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003383 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003384error:
3385 if (status < 0)
3386 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003387 return status;
3388}
3389
Oliver Endrissebc7de22011-07-03 13:49:44 -03003390static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003391{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003392 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003393 int status;
3394
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003395 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003396 status = CtrlPowerMode(state, &powerMode);
3397 if (status < 0)
3398 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003399 return status;
3400}
3401
Oliver Endrissebc7de22011-07-03 13:49:44 -03003402static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003403{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003404 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003405
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003406 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003407 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003408 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003409 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003410 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003411 if (status < 0)
3412 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003413 return status;
3414}
3415
3416#define DEFAULT_FR_THRES_8K 4000
3417static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3418{
3419
3420 int status;
3421
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003422 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003423 if (*enabled == true) {
3424 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003425 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003426 DEFAULT_FR_THRES_8K);
3427 } else {
3428 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003429 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003430 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003431 if (status < 0)
3432 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003433
3434 return status;
3435}
3436
3437static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3438 struct DRXKCfgDvbtEchoThres_t *echoThres)
3439{
3440 u16 data = 0;
3441 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003442
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003443 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003444 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3445 if (status < 0)
3446 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003447
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003448 switch (echoThres->fftMode) {
3449 case DRX_FFTMODE_2K:
3450 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3451 data |= ((echoThres->threshold <<
3452 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3453 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003454 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003455 case DRX_FFTMODE_8K:
3456 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3457 data |= ((echoThres->threshold <<
3458 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3459 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003460 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003461 default:
3462 return -EINVAL;
3463 goto error;
3464 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003465
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003466 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3467error:
3468 if (status < 0)
3469 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003470 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003471}
3472
3473static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003474 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003475{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003476 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003477
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003478 dprintk(1, "\n");
3479
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003480 switch (*speed) {
3481 case DRXK_DVBT_SQI_SPEED_FAST:
3482 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3483 case DRXK_DVBT_SQI_SPEED_SLOW:
3484 break;
3485 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003486 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003487 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003488 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003489 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003490error:
3491 if (status < 0)
3492 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003493 return status;
3494}
3495
3496/*============================================================================*/
3497
3498/**
3499* \brief Activate DVBT specific presets
3500* \param demod instance of demodulator.
3501* \return DRXStatus_t.
3502*
3503* Called in DVBTSetStandard
3504*
3505*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003506static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003507{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003508 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003509 bool setincenable = false;
3510 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003511
Oliver Endrissebc7de22011-07-03 13:49:44 -03003512 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3513 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003514
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003515 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003516 status = DVBTCtrlSetIncEnable(state, &setincenable);
3517 if (status < 0)
3518 goto error;
3519 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3520 if (status < 0)
3521 goto error;
3522 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3523 if (status < 0)
3524 goto error;
3525 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3526 if (status < 0)
3527 goto error;
3528 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3529error:
3530 if (status < 0)
3531 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003532 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003533}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003534
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003535/*============================================================================*/
3536
3537/**
3538* \brief Initialize channelswitch-independent settings for DVBT.
3539* \param demod instance of demodulator.
3540* \return DRXStatus_t.
3541*
3542* For ROM code channel filter taps are loaded from the bootloader. For microcode
3543* the DVB-T taps from the drxk_filters.h are used.
3544*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003545static int SetDVBTStandard(struct drxk_state *state,
3546 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003547{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003548 u16 cmdResult = 0;
3549 u16 data = 0;
3550 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003551
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003552 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003553
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003554 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003555 /* added antenna switch */
3556 SwitchAntennaToDVBT(state);
3557 /* send OFDM reset command */
3558 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 -03003559 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003560 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003561
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003562 /* send OFDM setenv command */
3563 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3564 if (status < 0)
3565 goto error;
3566
3567 /* reset datapath for OFDM, processors first */
3568 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3569 if (status < 0)
3570 goto error;
3571 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3572 if (status < 0)
3573 goto error;
3574 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3575 if (status < 0)
3576 goto error;
3577
3578 /* IQM setup */
3579 /* synchronize on ofdstate->m_festart */
3580 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3581 if (status < 0)
3582 goto error;
3583 /* window size for clipping ADC detection */
3584 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3585 if (status < 0)
3586 goto error;
3587 /* window size for for sense pre-SAW detection */
3588 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3589 if (status < 0)
3590 goto error;
3591 /* sense threshold for sense pre-SAW detection */
3592 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3593 if (status < 0)
3594 goto error;
3595 status = SetIqmAf(state, true);
3596 if (status < 0)
3597 goto error;
3598
3599 status = write16(state, IQM_AF_AGC_RF__A, 0);
3600 if (status < 0)
3601 goto error;
3602
3603 /* Impulse noise cruncher setup */
3604 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3605 if (status < 0)
3606 goto error;
3607 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3608 if (status < 0)
3609 goto error;
3610 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3611 if (status < 0)
3612 goto error;
3613
3614 status = write16(state, IQM_RC_STRETCH__A, 16);
3615 if (status < 0)
3616 goto error;
3617 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3618 if (status < 0)
3619 goto error;
3620 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3621 if (status < 0)
3622 goto error;
3623 status = write16(state, IQM_CF_SCALE__A, 1600);
3624 if (status < 0)
3625 goto error;
3626 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3627 if (status < 0)
3628 goto error;
3629
3630 /* virtual clipping threshold for clipping ADC detection */
3631 status = write16(state, IQM_AF_CLP_TH__A, 448);
3632 if (status < 0)
3633 goto error;
3634 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3635 if (status < 0)
3636 goto error;
3637
3638 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3639 if (status < 0)
3640 goto error;
3641
3642 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3643 if (status < 0)
3644 goto error;
3645 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3646 if (status < 0)
3647 goto error;
3648 /* enable power measurement interrupt */
3649 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3650 if (status < 0)
3651 goto error;
3652 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3653 if (status < 0)
3654 goto error;
3655
3656 /* IQM will not be reset from here, sync ADC and update/init AGC */
3657 status = ADCSynchronization(state);
3658 if (status < 0)
3659 goto error;
3660 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3661 if (status < 0)
3662 goto error;
3663
3664 /* Halt SCU to enable safe non-atomic accesses */
3665 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3666 if (status < 0)
3667 goto error;
3668
3669 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3670 if (status < 0)
3671 goto error;
3672 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3673 if (status < 0)
3674 goto error;
3675
3676 /* Set Noise Estimation notch width and enable DC fix */
3677 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3678 if (status < 0)
3679 goto error;
3680 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3681 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3682 if (status < 0)
3683 goto error;
3684
3685 /* Activate SCU to enable SCU commands */
3686 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3687 if (status < 0)
3688 goto error;
3689
3690 if (!state->m_DRXK_A3_ROM_CODE) {
3691 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3692 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3693 if (status < 0)
3694 goto error;
3695 }
3696
3697 /* OFDM_SC setup */
3698#ifdef COMPILE_FOR_NONRT
3699 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3700 if (status < 0)
3701 goto error;
3702 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3703 if (status < 0)
3704 goto error;
3705#endif
3706
3707 /* FEC setup */
3708 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3709 if (status < 0)
3710 goto error;
3711
3712
3713#ifdef COMPILE_FOR_NONRT
3714 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3715 if (status < 0)
3716 goto error;
3717#else
3718 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3719 if (status < 0)
3720 goto error;
3721#endif
3722 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3723 if (status < 0)
3724 goto error;
3725
3726 /* Setup MPEG bus */
3727 status = MPEGTSDtoSetup(state, OM_DVBT);
3728 if (status < 0)
3729 goto error;
3730 /* Set DVBT Presets */
3731 status = DVBTActivatePresets(state);
3732 if (status < 0)
3733 goto error;
3734
3735error:
3736 if (status < 0)
3737 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003738 return status;
3739}
3740
3741/*============================================================================*/
3742/**
3743* \brief Start dvbt demodulating for channel.
3744* \param demod instance of demodulator.
3745* \return DRXStatus_t.
3746*/
3747static int DVBTStart(struct drxk_state *state)
3748{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003749 u16 param1;
3750 int status;
3751 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003752
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003753 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003754 /* Start correct processes to get in lock */
3755 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003756 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3757 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3758 if (status < 0)
3759 goto error;
3760 /* Start FEC OC */
3761 status = MPEGTSStart(state);
3762 if (status < 0)
3763 goto error;
3764 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3765 if (status < 0)
3766 goto error;
3767error:
3768 if (status < 0)
3769 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003770 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003771}
3772
3773
3774/*============================================================================*/
3775
3776/**
3777* \brief Set up dvbt demodulator for channel.
3778* \param demod instance of demodulator.
3779* \return DRXStatus_t.
3780* // original DVBTSetChannel()
3781*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003782static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3783 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003784{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003785 u16 cmdResult = 0;
3786 u16 transmissionParams = 0;
3787 u16 operationMode = 0;
3788 u32 iqmRcRateOfs = 0;
3789 u32 bandwidth = 0;
3790 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003791 int status;
3792
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003793 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003794
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003795 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3796 if (status < 0)
3797 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003798
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003799 /* Halt SCU to enable safe non-atomic accesses */
3800 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3801 if (status < 0)
3802 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003803
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003804 /* Stop processors */
3805 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3806 if (status < 0)
3807 goto error;
3808 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3809 if (status < 0)
3810 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003811
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003812 /* Mandatory fix, always stop CP, required to set spl offset back to
3813 hardware default (is set to 0 by ucode during pilot detection */
3814 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3815 if (status < 0)
3816 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003817
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003818 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003819
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003820 /* mode */
3821 switch (state->param.u.ofdm.transmission_mode) {
3822 case TRANSMISSION_MODE_AUTO:
3823 default:
3824 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3825 /* fall through , try first guess DRX_FFTMODE_8K */
3826 case TRANSMISSION_MODE_8K:
3827 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003828 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003829 case TRANSMISSION_MODE_2K:
3830 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003831 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003832 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003833
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003834 /* guard */
3835 switch (state->param.u.ofdm.guard_interval) {
3836 default:
3837 case GUARD_INTERVAL_AUTO:
3838 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3839 /* fall through , try first guess DRX_GUARD_1DIV4 */
3840 case GUARD_INTERVAL_1_4:
3841 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003842 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003843 case GUARD_INTERVAL_1_32:
3844 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003845 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003846 case GUARD_INTERVAL_1_16:
3847 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003848 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003849 case GUARD_INTERVAL_1_8:
3850 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003851 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003852 }
3853
3854 /* hierarchy */
3855 switch (state->param.u.ofdm.hierarchy_information) {
3856 case HIERARCHY_AUTO:
3857 case HIERARCHY_NONE:
3858 default:
3859 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3860 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3861 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3862 /* break; */
3863 case HIERARCHY_1:
3864 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3865 break;
3866 case HIERARCHY_2:
3867 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3868 break;
3869 case HIERARCHY_4:
3870 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3871 break;
3872 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003873
3874
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003875 /* constellation */
3876 switch (state->param.u.ofdm.constellation) {
3877 case QAM_AUTO:
3878 default:
3879 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3880 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3881 case QAM_64:
3882 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3883 break;
3884 case QPSK:
3885 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3886 break;
3887 case QAM_16:
3888 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3889 break;
3890 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003891#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003892 /* No hierachical channels support in BDA */
3893 /* Priority (only for hierarchical channels) */
3894 switch (channel->priority) {
3895 case DRX_PRIORITY_LOW:
3896 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3897 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3898 OFDM_EC_SB_PRIOR_LO);
3899 break;
3900 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003901 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003902 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3903 OFDM_EC_SB_PRIOR_HI));
3904 break;
3905 case DRX_PRIORITY_UNKNOWN: /* fall through */
3906 default:
3907 status = -EINVAL;
3908 goto error;
3909 }
3910#else
3911 /* Set Priorty high */
3912 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3913 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3914 if (status < 0)
3915 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003916#endif
3917
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003918 /* coderate */
3919 switch (state->param.u.ofdm.code_rate_HP) {
3920 case FEC_AUTO:
3921 default:
3922 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3923 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3924 case FEC_2_3:
3925 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3926 break;
3927 case FEC_1_2:
3928 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3929 break;
3930 case FEC_3_4:
3931 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3932 break;
3933 case FEC_5_6:
3934 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3935 break;
3936 case FEC_7_8:
3937 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3938 break;
3939 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003940
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003941 /* SAW filter selection: normaly not necesarry, but if wanted
3942 the application can select a SAW filter via the driver by using UIOs */
3943 /* First determine real bandwidth (Hz) */
3944 /* Also set delay for impulse noise cruncher */
3945 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3946 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3947 functions */
3948 switch (state->param.u.ofdm.bandwidth) {
3949 case BANDWIDTH_AUTO:
3950 case BANDWIDTH_8_MHZ:
3951 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3952 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003953 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003954 goto error;
3955 /* cochannel protection for PAL 8 MHz */
3956 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3957 if (status < 0)
3958 goto error;
3959 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3960 if (status < 0)
3961 goto error;
3962 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3963 if (status < 0)
3964 goto error;
3965 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3966 if (status < 0)
3967 goto error;
3968 break;
3969 case BANDWIDTH_7_MHZ:
3970 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3971 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3972 if (status < 0)
3973 goto error;
3974 /* cochannel protection for PAL 7 MHz */
3975 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3976 if (status < 0)
3977 goto error;
3978 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3979 if (status < 0)
3980 goto error;
3981 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3982 if (status < 0)
3983 goto error;
3984 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3985 if (status < 0)
3986 goto error;
3987 break;
3988 case BANDWIDTH_6_MHZ:
3989 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3990 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3991 if (status < 0)
3992 goto error;
3993 /* cochannel protection for NTSC 6 MHz */
3994 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3995 if (status < 0)
3996 goto error;
3997 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3998 if (status < 0)
3999 goto error;
4000 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
4001 if (status < 0)
4002 goto error;
4003 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
4004 if (status < 0)
4005 goto error;
4006 break;
4007 default:
4008 status = -EINVAL;
4009 goto error;
4010 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004011
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004012 if (iqmRcRateOfs == 0) {
4013 /* Now compute IQM_RC_RATE_OFS
4014 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4015 =>
4016 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4017 */
4018 /* (SysFreq / BandWidth) * (2^28) */
4019 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4020 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4021 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4022 iqmRcRateOfs = Frac28a((u32)
4023 ((state->m_sysClockFreq *
4024 1000) / 3), bandwidth);
4025 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4026 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4027 iqmRcRateOfs += 0x80L;
4028 iqmRcRateOfs = iqmRcRateOfs >> 7;
4029 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4030 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4031 }
4032
4033 iqmRcRateOfs &=
4034 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4035 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4036 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4037 if (status < 0)
4038 goto error;
4039
4040 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004041
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004042#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004043 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4044 if (status < 0)
4045 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004046#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004047 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4048 if (status < 0)
4049 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004050
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004051 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004052
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004053 /* Activate SCU to enable SCU commands */
4054 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4055 if (status < 0)
4056 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004057
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004058 /* Enable SC after setting all other parameters */
4059 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4060 if (status < 0)
4061 goto error;
4062 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4063 if (status < 0)
4064 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004065
4066
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004067 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4068 if (status < 0)
4069 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004070
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004071 /* Write SC parameter registers, set all AUTO flags in operation mode */
4072 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4073 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4074 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4075 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4076 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4077 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4078 0, transmissionParams, param1, 0, 0, 0);
4079 if (status < 0)
4080 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004081
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004082 if (!state->m_DRXK_A3_ROM_CODE)
4083 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4084error:
4085 if (status < 0)
4086 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004087
4088 return status;
4089}
4090
4091
4092/*============================================================================*/
4093
4094/**
4095* \brief Retreive lock status .
4096* \param demod Pointer to demodulator instance.
4097* \param lockStat Pointer to lock status structure.
4098* \return DRXStatus_t.
4099*
4100*/
4101static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4102{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004103 int status;
4104 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4105 OFDM_SC_RA_RAM_LOCK_FEC__M);
4106 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4107 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004108
Oliver Endrissebc7de22011-07-03 13:49:44 -03004109 u16 ScRaRamLock = 0;
4110 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004111
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004112 dprintk(1, "\n");
4113
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004114 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004115 /* driver 0.9.0 */
4116 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004117 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004118 if (status < 0)
4119 goto end;
4120 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4121 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004122
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004123 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004124 if (status < 0)
4125 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004126
Oliver Endrissebc7de22011-07-03 13:49:44 -03004127 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4128 *pLockStatus = MPEG_LOCK;
4129 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4130 *pLockStatus = FEC_LOCK;
4131 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4132 *pLockStatus = DEMOD_LOCK;
4133 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4134 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004135end:
4136 if (status < 0)
4137 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004138
Oliver Endrissebc7de22011-07-03 13:49:44 -03004139 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004140}
4141
Oliver Endrissebc7de22011-07-03 13:49:44 -03004142static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004143{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004144 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004145 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004146
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004147 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004148 status = CtrlPowerMode(state, &powerMode);
4149 if (status < 0)
4150 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004151
Oliver Endrissebc7de22011-07-03 13:49:44 -03004152 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004153}
4154
4155
Oliver Endrissebc7de22011-07-03 13:49:44 -03004156/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004157static int PowerDownQAM(struct drxk_state *state)
4158{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004159 u16 data = 0;
4160 u16 cmdResult;
4161 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004162
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004163 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004164 status = read16(state, SCU_COMM_EXEC__A, &data);
4165 if (status < 0)
4166 goto error;
4167 if (data == SCU_COMM_EXEC_ACTIVE) {
4168 /*
4169 STOP demodulator
4170 QAM and HW blocks
4171 */
4172 /* stop all comstate->m_exec */
4173 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004174 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004175 goto error;
4176 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 -03004177 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004178 goto error;
4179 }
4180 /* powerdown AFE */
4181 status = SetIqmAf(state, false);
4182
4183error:
4184 if (status < 0)
4185 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004186
Oliver Endrissebc7de22011-07-03 13:49:44 -03004187 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004188}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004189
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004190/*============================================================================*/
4191
4192/**
4193* \brief Setup of the QAM Measurement intervals for signal quality
4194* \param demod instance of demod.
4195* \param constellation current constellation.
4196* \return DRXStatus_t.
4197*
4198* NOTE:
4199* Take into account that for certain settings the errorcounters can overflow.
4200* The implementation does not check this.
4201*
4202*/
4203static int SetQAMMeasurement(struct drxk_state *state,
4204 enum EDrxkConstellation constellation,
4205 u32 symbolRate)
4206{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004207 u32 fecBitsDesired = 0; /* BER accounting period */
4208 u32 fecRsPeriodTotal = 0; /* Total period */
4209 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4210 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004211 int status = 0;
4212
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004213 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004214
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004215 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004216 /* fecBitsDesired = symbolRate [kHz] *
4217 FrameLenght [ms] *
4218 (constellation + 1) *
4219 SyncLoss (== 1) *
4220 ViterbiLoss (==1)
4221 */
4222 switch (constellation) {
4223 case DRX_CONSTELLATION_QAM16:
4224 fecBitsDesired = 4 * symbolRate;
4225 break;
4226 case DRX_CONSTELLATION_QAM32:
4227 fecBitsDesired = 5 * symbolRate;
4228 break;
4229 case DRX_CONSTELLATION_QAM64:
4230 fecBitsDesired = 6 * symbolRate;
4231 break;
4232 case DRX_CONSTELLATION_QAM128:
4233 fecBitsDesired = 7 * symbolRate;
4234 break;
4235 case DRX_CONSTELLATION_QAM256:
4236 fecBitsDesired = 8 * symbolRate;
4237 break;
4238 default:
4239 status = -EINVAL;
4240 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004241 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004242 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004243
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004244 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4245 fecBitsDesired *= 500; /* meas. period [ms] */
4246
4247 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4248 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4249 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4250
4251 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4252 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4253 if (fecRsPrescale == 0) {
4254 /* Divide by zero (though impossible) */
4255 status = -EINVAL;
4256 if (status < 0)
4257 goto error;
4258 }
4259 fecRsPeriod =
4260 ((u16) fecRsPeriodTotal +
4261 (fecRsPrescale >> 1)) / fecRsPrescale;
4262
4263 /* write corresponding registers */
4264 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4265 if (status < 0)
4266 goto error;
4267 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4268 if (status < 0)
4269 goto error;
4270 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4271error:
4272 if (status < 0)
4273 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004274 return status;
4275}
4276
Oliver Endrissebc7de22011-07-03 13:49:44 -03004277static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004278{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004279 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004280
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004281 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004282 /* QAM Equalizer Setup */
4283 /* Equalizer */
4284 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4285 if (status < 0)
4286 goto error;
4287 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4288 if (status < 0)
4289 goto error;
4290 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4291 if (status < 0)
4292 goto error;
4293 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4294 if (status < 0)
4295 goto error;
4296 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4297 if (status < 0)
4298 goto error;
4299 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4300 if (status < 0)
4301 goto error;
4302 /* Decision Feedback Equalizer */
4303 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4304 if (status < 0)
4305 goto error;
4306 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4307 if (status < 0)
4308 goto error;
4309 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4310 if (status < 0)
4311 goto error;
4312 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4313 if (status < 0)
4314 goto error;
4315 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4316 if (status < 0)
4317 goto error;
4318 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4319 if (status < 0)
4320 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004321
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004322 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4323 if (status < 0)
4324 goto error;
4325 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4326 if (status < 0)
4327 goto error;
4328 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4329 if (status < 0)
4330 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004331
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004332 /* QAM Slicer Settings */
4333 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4334 if (status < 0)
4335 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004336
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004337 /* QAM Loop Controller Coeficients */
4338 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4339 if (status < 0)
4340 goto error;
4341 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4342 if (status < 0)
4343 goto error;
4344 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4345 if (status < 0)
4346 goto error;
4347 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4348 if (status < 0)
4349 goto error;
4350 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4351 if (status < 0)
4352 goto error;
4353 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4354 if (status < 0)
4355 goto error;
4356 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4357 if (status < 0)
4358 goto error;
4359 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4360 if (status < 0)
4361 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004362
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004363 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4364 if (status < 0)
4365 goto error;
4366 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4367 if (status < 0)
4368 goto error;
4369 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4370 if (status < 0)
4371 goto error;
4372 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4373 if (status < 0)
4374 goto error;
4375 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4376 if (status < 0)
4377 goto error;
4378 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4379 if (status < 0)
4380 goto error;
4381 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4382 if (status < 0)
4383 goto error;
4384 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4385 if (status < 0)
4386 goto error;
4387 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4388 if (status < 0)
4389 goto error;
4390 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4391 if (status < 0)
4392 goto error;
4393 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4394 if (status < 0)
4395 goto error;
4396 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4397 if (status < 0)
4398 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004399
4400
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004401 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004402
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004403 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4404 if (status < 0)
4405 goto error;
4406 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4407 if (status < 0)
4408 goto error;
4409 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4410 if (status < 0)
4411 goto error;
4412 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4413 if (status < 0)
4414 goto error;
4415 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4416 if (status < 0)
4417 goto error;
4418 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4419 if (status < 0)
4420 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004421
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004422 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4423 if (status < 0)
4424 goto error;
4425 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4426 if (status < 0)
4427 goto error;
4428 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4429 if (status < 0)
4430 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004431
4432
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004433 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004434
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004435 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4436 if (status < 0)
4437 goto error;
4438 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4439 if (status < 0)
4440 goto error;
4441 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4442 if (status < 0)
4443 goto error;
4444 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4445 if (status < 0)
4446 goto error;
4447 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4448 if (status < 0)
4449 goto error;
4450 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4451 if (status < 0)
4452 goto error;
4453 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4454 if (status < 0)
4455 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004456
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004457error:
4458 if (status < 0)
4459 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004460 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004461}
4462
4463/*============================================================================*/
4464
4465/**
4466* \brief QAM32 specific setup
4467* \param demod instance of demod.
4468* \return DRXStatus_t.
4469*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004470static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004471{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004472 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004473
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004474 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004475
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004476 /* QAM Equalizer Setup */
4477 /* Equalizer */
4478 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4479 if (status < 0)
4480 goto error;
4481 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4482 if (status < 0)
4483 goto error;
4484 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4485 if (status < 0)
4486 goto error;
4487 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4488 if (status < 0)
4489 goto error;
4490 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4491 if (status < 0)
4492 goto error;
4493 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4494 if (status < 0)
4495 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004496
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004497 /* Decision Feedback Equalizer */
4498 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4499 if (status < 0)
4500 goto error;
4501 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4502 if (status < 0)
4503 goto error;
4504 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4505 if (status < 0)
4506 goto error;
4507 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4508 if (status < 0)
4509 goto error;
4510 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4511 if (status < 0)
4512 goto error;
4513 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4514 if (status < 0)
4515 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004516
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004517 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4518 if (status < 0)
4519 goto error;
4520 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4521 if (status < 0)
4522 goto error;
4523 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4524 if (status < 0)
4525 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004526
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004527 /* QAM Slicer Settings */
4528
4529 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4530 if (status < 0)
4531 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004532
4533
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004534 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004535
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004536 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4537 if (status < 0)
4538 goto error;
4539 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4540 if (status < 0)
4541 goto error;
4542 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4543 if (status < 0)
4544 goto error;
4545 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4546 if (status < 0)
4547 goto error;
4548 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4549 if (status < 0)
4550 goto error;
4551 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4552 if (status < 0)
4553 goto error;
4554 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4555 if (status < 0)
4556 goto error;
4557 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4558 if (status < 0)
4559 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004560
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004561 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4562 if (status < 0)
4563 goto error;
4564 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4565 if (status < 0)
4566 goto error;
4567 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4568 if (status < 0)
4569 goto error;
4570 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4571 if (status < 0)
4572 goto error;
4573 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4574 if (status < 0)
4575 goto error;
4576 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4577 if (status < 0)
4578 goto error;
4579 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4580 if (status < 0)
4581 goto error;
4582 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4583 if (status < 0)
4584 goto error;
4585 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4586 if (status < 0)
4587 goto error;
4588 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4589 if (status < 0)
4590 goto error;
4591 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4592 if (status < 0)
4593 goto error;
4594 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4595 if (status < 0)
4596 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004597
4598
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004599 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004600
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004601 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4602 if (status < 0)
4603 goto error;
4604 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4605 if (status < 0)
4606 goto error;
4607 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4608 if (status < 0)
4609 goto error;
4610 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4611 if (status < 0)
4612 goto error;
4613 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4614 if (status < 0)
4615 goto error;
4616 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4617 if (status < 0)
4618 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004619
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004620 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4621 if (status < 0)
4622 goto error;
4623 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4624 if (status < 0)
4625 goto error;
4626 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4627 if (status < 0)
4628 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004629
4630
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004631 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004632
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004633 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4634 if (status < 0)
4635 goto error;
4636 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4637 if (status < 0)
4638 goto error;
4639 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4640 if (status < 0)
4641 goto error;
4642 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4643 if (status < 0)
4644 goto error;
4645 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4646 if (status < 0)
4647 goto error;
4648 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4649 if (status < 0)
4650 goto error;
4651 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4652error:
4653 if (status < 0)
4654 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004655 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004656}
4657
4658/*============================================================================*/
4659
4660/**
4661* \brief QAM64 specific setup
4662* \param demod instance of demod.
4663* \return DRXStatus_t.
4664*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004665static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004666{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004667 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004668
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004669 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004670 /* QAM Equalizer Setup */
4671 /* Equalizer */
4672 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4673 if (status < 0)
4674 goto error;
4675 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4676 if (status < 0)
4677 goto error;
4678 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4679 if (status < 0)
4680 goto error;
4681 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4682 if (status < 0)
4683 goto error;
4684 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4685 if (status < 0)
4686 goto error;
4687 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4688 if (status < 0)
4689 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004690
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004691 /* Decision Feedback Equalizer */
4692 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4693 if (status < 0)
4694 goto error;
4695 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4696 if (status < 0)
4697 goto error;
4698 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4699 if (status < 0)
4700 goto error;
4701 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4702 if (status < 0)
4703 goto error;
4704 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4705 if (status < 0)
4706 goto error;
4707 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4708 if (status < 0)
4709 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004710
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004711 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4712 if (status < 0)
4713 goto error;
4714 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4715 if (status < 0)
4716 goto error;
4717 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4718 if (status < 0)
4719 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004720
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004721 /* QAM Slicer Settings */
4722 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4723 if (status < 0)
4724 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004725
4726
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004727 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004728
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004729 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4730 if (status < 0)
4731 goto error;
4732 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4733 if (status < 0)
4734 goto error;
4735 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4736 if (status < 0)
4737 goto error;
4738 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4739 if (status < 0)
4740 goto error;
4741 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4742 if (status < 0)
4743 goto error;
4744 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4745 if (status < 0)
4746 goto error;
4747 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4748 if (status < 0)
4749 goto error;
4750 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4751 if (status < 0)
4752 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004753
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004754 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4755 if (status < 0)
4756 goto error;
4757 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4758 if (status < 0)
4759 goto error;
4760 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4761 if (status < 0)
4762 goto error;
4763 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4764 if (status < 0)
4765 goto error;
4766 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4767 if (status < 0)
4768 goto error;
4769 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4770 if (status < 0)
4771 goto error;
4772 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4773 if (status < 0)
4774 goto error;
4775 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4776 if (status < 0)
4777 goto error;
4778 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4779 if (status < 0)
4780 goto error;
4781 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4782 if (status < 0)
4783 goto error;
4784 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4785 if (status < 0)
4786 goto error;
4787 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4788 if (status < 0)
4789 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004790
4791
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004792 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004793
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004794 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4795 if (status < 0)
4796 goto error;
4797 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4798 if (status < 0)
4799 goto error;
4800 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4801 if (status < 0)
4802 goto error;
4803 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4804 if (status < 0)
4805 goto error;
4806 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4807 if (status < 0)
4808 goto error;
4809 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4810 if (status < 0)
4811 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004812
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004813 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4814 if (status < 0)
4815 goto error;
4816 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4817 if (status < 0)
4818 goto error;
4819 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4820 if (status < 0)
4821 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004822
4823
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004824 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004825
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004826 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4827 if (status < 0)
4828 goto error;
4829 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4830 if (status < 0)
4831 goto error;
4832 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4833 if (status < 0)
4834 goto error;
4835 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4836 if (status < 0)
4837 goto error;
4838 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4839 if (status < 0)
4840 goto error;
4841 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4842 if (status < 0)
4843 goto error;
4844 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4845error:
4846 if (status < 0)
4847 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004848
Oliver Endrissebc7de22011-07-03 13:49:44 -03004849 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004850}
4851
4852/*============================================================================*/
4853
4854/**
4855* \brief QAM128 specific setup
4856* \param demod: instance of demod.
4857* \return DRXStatus_t.
4858*/
4859static int SetQAM128(struct drxk_state *state)
4860{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004861 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004862
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004863 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004864 /* QAM Equalizer Setup */
4865 /* Equalizer */
4866 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4867 if (status < 0)
4868 goto error;
4869 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4870 if (status < 0)
4871 goto error;
4872 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4873 if (status < 0)
4874 goto error;
4875 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4876 if (status < 0)
4877 goto error;
4878 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4879 if (status < 0)
4880 goto error;
4881 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4882 if (status < 0)
4883 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004884
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004885 /* Decision Feedback Equalizer */
4886 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4887 if (status < 0)
4888 goto error;
4889 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4890 if (status < 0)
4891 goto error;
4892 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4893 if (status < 0)
4894 goto error;
4895 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4896 if (status < 0)
4897 goto error;
4898 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4899 if (status < 0)
4900 goto error;
4901 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4902 if (status < 0)
4903 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004904
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004905 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4906 if (status < 0)
4907 goto error;
4908 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4909 if (status < 0)
4910 goto error;
4911 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4912 if (status < 0)
4913 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004914
4915
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004916 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004917
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004918 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4919 if (status < 0)
4920 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004921
4922
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004923 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004924
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004925 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4926 if (status < 0)
4927 goto error;
4928 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4929 if (status < 0)
4930 goto error;
4931 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4932 if (status < 0)
4933 goto error;
4934 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4935 if (status < 0)
4936 goto error;
4937 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4938 if (status < 0)
4939 goto error;
4940 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4941 if (status < 0)
4942 goto error;
4943 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4944 if (status < 0)
4945 goto error;
4946 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4947 if (status < 0)
4948 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004949
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004950 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4951 if (status < 0)
4952 goto error;
4953 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4954 if (status < 0)
4955 goto error;
4956 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4957 if (status < 0)
4958 goto error;
4959 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4960 if (status < 0)
4961 goto error;
4962 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4963 if (status < 0)
4964 goto error;
4965 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4966 if (status < 0)
4967 goto error;
4968 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4969 if (status < 0)
4970 goto error;
4971 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4972 if (status < 0)
4973 goto error;
4974 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4975 if (status < 0)
4976 goto error;
4977 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4978 if (status < 0)
4979 goto error;
4980 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4981 if (status < 0)
4982 goto error;
4983 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4984 if (status < 0)
4985 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004986
4987
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004988 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004989
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004990 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4991 if (status < 0)
4992 goto error;
4993 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4994 if (status < 0)
4995 goto error;
4996 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4997 if (status < 0)
4998 goto error;
4999 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5000 if (status < 0)
5001 goto error;
5002 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
5003 if (status < 0)
5004 goto error;
5005 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5006 if (status < 0)
5007 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005008
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005009 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5010 if (status < 0)
5011 goto error;
5012 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5013 if (status < 0)
5014 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005015
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005016 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5017 if (status < 0)
5018 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005019
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005020 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005021
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005022 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5023 if (status < 0)
5024 goto error;
5025 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5026 if (status < 0)
5027 goto error;
5028 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5029 if (status < 0)
5030 goto error;
5031 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5032 if (status < 0)
5033 goto error;
5034 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5035 if (status < 0)
5036 goto error;
5037 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5038 if (status < 0)
5039 goto error;
5040 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5041error:
5042 if (status < 0)
5043 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005044
Oliver Endrissebc7de22011-07-03 13:49:44 -03005045 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005046}
5047
5048/*============================================================================*/
5049
5050/**
5051* \brief QAM256 specific setup
5052* \param demod: instance of demod.
5053* \return DRXStatus_t.
5054*/
5055static int SetQAM256(struct drxk_state *state)
5056{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005057 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005058
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005059 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005060 /* QAM Equalizer Setup */
5061 /* Equalizer */
5062 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5063 if (status < 0)
5064 goto error;
5065 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5066 if (status < 0)
5067 goto error;
5068 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5069 if (status < 0)
5070 goto error;
5071 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5072 if (status < 0)
5073 goto error;
5074 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5075 if (status < 0)
5076 goto error;
5077 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5078 if (status < 0)
5079 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005080
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005081 /* Decision Feedback Equalizer */
5082 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5083 if (status < 0)
5084 goto error;
5085 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5086 if (status < 0)
5087 goto error;
5088 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5089 if (status < 0)
5090 goto error;
5091 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5092 if (status < 0)
5093 goto error;
5094 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5095 if (status < 0)
5096 goto error;
5097 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5098 if (status < 0)
5099 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005100
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005101 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5102 if (status < 0)
5103 goto error;
5104 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5105 if (status < 0)
5106 goto error;
5107 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5108 if (status < 0)
5109 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005110
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005111 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005112
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005113 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5114 if (status < 0)
5115 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005116
5117
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005118 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005119
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005120 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5121 if (status < 0)
5122 goto error;
5123 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5124 if (status < 0)
5125 goto error;
5126 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5127 if (status < 0)
5128 goto error;
5129 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5130 if (status < 0)
5131 goto error;
5132 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5133 if (status < 0)
5134 goto error;
5135 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5136 if (status < 0)
5137 goto error;
5138 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5139 if (status < 0)
5140 goto error;
5141 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5142 if (status < 0)
5143 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005144
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005145 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5146 if (status < 0)
5147 goto error;
5148 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5149 if (status < 0)
5150 goto error;
5151 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5152 if (status < 0)
5153 goto error;
5154 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5155 if (status < 0)
5156 goto error;
5157 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5158 if (status < 0)
5159 goto error;
5160 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5161 if (status < 0)
5162 goto error;
5163 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5164 if (status < 0)
5165 goto error;
5166 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5167 if (status < 0)
5168 goto error;
5169 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5170 if (status < 0)
5171 goto error;
5172 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5173 if (status < 0)
5174 goto error;
5175 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5176 if (status < 0)
5177 goto error;
5178 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5179 if (status < 0)
5180 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005181
5182
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005183 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005184
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005185 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5186 if (status < 0)
5187 goto error;
5188 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5189 if (status < 0)
5190 goto error;
5191 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5192 if (status < 0)
5193 goto error;
5194 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5195 if (status < 0)
5196 goto error;
5197 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5198 if (status < 0)
5199 goto error;
5200 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5201 if (status < 0)
5202 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005203
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005204 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5205 if (status < 0)
5206 goto error;
5207 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5208 if (status < 0)
5209 goto error;
5210 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5211 if (status < 0)
5212 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005213
5214
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005215 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005216
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005217 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5218 if (status < 0)
5219 goto error;
5220 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5221 if (status < 0)
5222 goto error;
5223 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5224 if (status < 0)
5225 goto error;
5226 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5227 if (status < 0)
5228 goto error;
5229 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5230 if (status < 0)
5231 goto error;
5232 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5233 if (status < 0)
5234 goto error;
5235 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5236error:
5237 if (status < 0)
5238 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005239 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005240}
5241
5242
5243/*============================================================================*/
5244/**
5245* \brief Reset QAM block.
5246* \param demod: instance of demod.
5247* \param channel: pointer to channel data.
5248* \return DRXStatus_t.
5249*/
5250static int QAMResetQAM(struct drxk_state *state)
5251{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005252 int status;
5253 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005254
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005255 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005256 /* Stop QAM comstate->m_exec */
5257 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5258 if (status < 0)
5259 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005260
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005261 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5262error:
5263 if (status < 0)
5264 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005265 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005266}
5267
5268/*============================================================================*/
5269
5270/**
5271* \brief Set QAM symbolrate.
5272* \param demod: instance of demod.
5273* \param channel: pointer to channel data.
5274* \return DRXStatus_t.
5275*/
5276static int QAMSetSymbolrate(struct drxk_state *state)
5277{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005278 u32 adcFrequency = 0;
5279 u32 symbFreq = 0;
5280 u32 iqmRcRate = 0;
5281 u16 ratesel = 0;
5282 u32 lcSymbRate = 0;
5283 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005284
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005285 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005286 /* Select & calculate correct IQM rate */
5287 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5288 ratesel = 0;
5289 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
5290 if (state->param.u.qam.symbol_rate <= 1188750)
5291 ratesel = 3;
5292 else if (state->param.u.qam.symbol_rate <= 2377500)
5293 ratesel = 2;
5294 else if (state->param.u.qam.symbol_rate <= 4755000)
5295 ratesel = 1;
5296 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5297 if (status < 0)
5298 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005299
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005300 /*
5301 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5302 */
5303 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5304 if (symbFreq == 0) {
5305 /* Divide by zero */
5306 status = -EINVAL;
5307 goto error;
5308 }
5309 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5310 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5311 (1 << 23);
5312 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5313 if (status < 0)
5314 goto error;
5315 state->m_iqmRcRate = iqmRcRate;
5316 /*
5317 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5318 */
5319 symbFreq = state->param.u.qam.symbol_rate;
5320 if (adcFrequency == 0) {
5321 /* Divide by zero */
5322 status = -EINVAL;
5323 goto error;
5324 }
5325 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5326 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5327 16);
5328 if (lcSymbRate > 511)
5329 lcSymbRate = 511;
5330 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005331
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005332error:
5333 if (status < 0)
5334 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005335 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005336}
5337
5338/*============================================================================*/
5339
5340/**
5341* \brief Get QAM lock status.
5342* \param demod: instance of demod.
5343* \param channel: pointer to channel data.
5344* \return DRXStatus_t.
5345*/
5346
5347static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5348{
5349 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005350 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005351
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005352 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005353 *pLockStatus = NOT_LOCKED;
5354 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005355 SCU_RAM_COMMAND_STANDARD_QAM |
5356 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5357 Result);
5358 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005359 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005360
5361 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005362 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005363 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005364 /* 0x4000 DEMOD LOCKED */
5365 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005366 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005367 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5368 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005369 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005370 /* 0xC000 NEVER LOCKED */
5371 /* (system will never be able to lock to the signal) */
5372 /* TODO: check this, intermediate & standard specific lock states are not
5373 taken into account here */
5374 *pLockStatus = NEVER_LOCK;
5375 }
5376 return status;
5377}
5378
5379#define QAM_MIRROR__M 0x03
5380#define QAM_MIRROR_NORMAL 0x00
5381#define QAM_MIRRORED 0x01
5382#define QAM_MIRROR_AUTO_ON 0x02
5383#define QAM_LOCKRANGE__M 0x10
5384#define QAM_LOCKRANGE_NORMAL 0x10
5385
Oliver Endrissebc7de22011-07-03 13:49:44 -03005386static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5387 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005388{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005389 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005390 u8 parameterLen;
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005391 u16 setEnvParameters[5] = { 0, 0, 0, 0, 0 };
Oliver Endrissebc7de22011-07-03 13:49:44 -03005392 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5393 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005394
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005395 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005396 /*
5397 STEP 1: reset demodulator
5398 resets FEC DI and FEC RS
5399 resets QAM block
5400 resets SCU variables
5401 */
5402 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005403 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005404 goto error;
5405 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5406 if (status < 0)
5407 goto error;
5408 status = QAMResetQAM(state);
5409 if (status < 0)
5410 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005411
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005412 /*
5413 STEP 2: configure demodulator
5414 -set env
5415 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5416 */
5417 status = QAMSetSymbolrate(state);
5418 if (status < 0)
5419 goto error;
5420
5421 /* Env parameters */
5422 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
5423 if (state->m_OperationMode == OM_QAM_ITU_C)
5424 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
5425 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5426 /* check for LOCKRANGE Extented */
5427 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5428 parameterLen = 4;
5429
5430 /* Set params */
5431 switch (state->param.u.qam.modulation) {
5432 case QAM_256:
5433 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5434 break;
5435 case QAM_AUTO:
5436 case QAM_64:
5437 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5438 break;
5439 case QAM_16:
5440 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5441 break;
5442 case QAM_32:
5443 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5444 break;
5445 case QAM_128:
5446 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5447 break;
5448 default:
5449 status = -EINVAL;
5450 break;
5451 }
5452 if (status < 0)
5453 goto error;
5454 setParamParameters[0] = state->m_Constellation; /* constellation */
5455 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5456
5457 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005458 if (status < 0) {
5459 /* Fall-back to the simpler call */
5460 setParamParameters[0] = QAM_TOP_ANNEX_A;
5461 if (state->m_OperationMode == OM_QAM_ITU_C)
5462 setEnvParameters[0] = QAM_TOP_ANNEX_C; /* Annex */
5463 else
5464 setEnvParameters[0] = 0;
5465
5466 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setEnvParameters, 1, &cmdResult);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005467 if (status < 0)
5468 goto error;
5469
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005470 setParamParameters[0] = state->m_Constellation; /* constellation */
5471 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5472
5473 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
5474 }
5475 if (status < 0)
5476 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005477
5478 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5479 setup constellation independent registers */
5480#if 0
5481 status = SetFrequency(channel, tunerFreqOffset));
5482 if (status < 0)
5483 goto error;
5484#endif
5485 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5486 if (status < 0)
5487 goto error;
5488
5489 /* Setup BER measurement */
5490 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5491 if (status < 0)
5492 goto error;
5493
5494 /* Reset default values */
5495 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5496 if (status < 0)
5497 goto error;
5498 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5499 if (status < 0)
5500 goto error;
5501
5502 /* Reset default LC values */
5503 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5504 if (status < 0)
5505 goto error;
5506 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5507 if (status < 0)
5508 goto error;
5509 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5510 if (status < 0)
5511 goto error;
5512 status = write16(state, QAM_LC_MODE__A, 7);
5513 if (status < 0)
5514 goto error;
5515
5516 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5517 if (status < 0)
5518 goto error;
5519 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5520 if (status < 0)
5521 goto error;
5522 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5523 if (status < 0)
5524 goto error;
5525 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5526 if (status < 0)
5527 goto error;
5528 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5529 if (status < 0)
5530 goto error;
5531 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5532 if (status < 0)
5533 goto error;
5534 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5535 if (status < 0)
5536 goto error;
5537 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5538 if (status < 0)
5539 goto error;
5540 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5541 if (status < 0)
5542 goto error;
5543 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5544 if (status < 0)
5545 goto error;
5546 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5547 if (status < 0)
5548 goto error;
5549 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5550 if (status < 0)
5551 goto error;
5552 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5553 if (status < 0)
5554 goto error;
5555 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5556 if (status < 0)
5557 goto error;
5558 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5559 if (status < 0)
5560 goto error;
5561
5562 /* Mirroring, QAM-block starting point not inverted */
5563 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5564 if (status < 0)
5565 goto error;
5566
5567 /* Halt SCU to enable safe non-atomic accesses */
5568 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5569 if (status < 0)
5570 goto error;
5571
5572 /* STEP 4: constellation specific setup */
5573 switch (state->param.u.qam.modulation) {
5574 case QAM_16:
5575 status = SetQAM16(state);
5576 break;
5577 case QAM_32:
5578 status = SetQAM32(state);
5579 break;
5580 case QAM_AUTO:
5581 case QAM_64:
5582 status = SetQAM64(state);
5583 break;
5584 case QAM_128:
5585 status = SetQAM128(state);
5586 break;
5587 case QAM_256:
5588 status = SetQAM256(state);
5589 break;
5590 default:
5591 status = -EINVAL;
5592 break;
5593 }
5594 if (status < 0)
5595 goto error;
5596
5597 /* Activate SCU to enable SCU commands */
5598 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5599 if (status < 0)
5600 goto error;
5601
5602 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5603 /* extAttr->currentChannel.constellation = channel->constellation; */
5604 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5605 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5606 if (status < 0)
5607 goto error;
5608
5609 /* Start processes */
5610 status = MPEGTSStart(state);
5611 if (status < 0)
5612 goto error;
5613 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5614 if (status < 0)
5615 goto error;
5616 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5617 if (status < 0)
5618 goto error;
5619 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5620 if (status < 0)
5621 goto error;
5622
5623 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5624 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5625 if (status < 0)
5626 goto error;
5627
5628 /* update global DRXK data container */
5629/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5630
5631error:
5632 if (status < 0)
5633 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005634 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005635}
5636
Oliver Endrissebc7de22011-07-03 13:49:44 -03005637static int SetQAMStandard(struct drxk_state *state,
5638 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005639{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005640 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005641#ifdef DRXK_QAM_TAPS
5642#define DRXK_QAMA_TAPS_SELECT
5643#include "drxk_filters.h"
5644#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005645#endif
5646
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005647 dprintk(1, "\n");
5648
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005649 /* added antenna switch */
5650 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005651
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005652 /* Ensure correct power-up mode */
5653 status = PowerUpQAM(state);
5654 if (status < 0)
5655 goto error;
5656 /* Reset QAM block */
5657 status = QAMResetQAM(state);
5658 if (status < 0)
5659 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005660
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005661 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005662
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005663 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5664 if (status < 0)
5665 goto error;
5666 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5667 if (status < 0)
5668 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005669
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005670 /* Upload IQM Channel Filter settings by
5671 boot loader from ROM table */
5672 switch (oMode) {
5673 case OM_QAM_ITU_A:
5674 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5675 break;
5676 case OM_QAM_ITU_C:
5677 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 -03005678 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005679 goto error;
5680 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5681 break;
5682 default:
5683 status = -EINVAL;
5684 }
5685 if (status < 0)
5686 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005687
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005688 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5689 if (status < 0)
5690 goto error;
5691 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5692 if (status < 0)
5693 goto error;
5694 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5695 if (status < 0)
5696 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005697
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005698 status = write16(state, IQM_RC_STRETCH__A, 21);
5699 if (status < 0)
5700 goto error;
5701 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5702 if (status < 0)
5703 goto error;
5704 status = write16(state, IQM_AF_CLP_TH__A, 448);
5705 if (status < 0)
5706 goto error;
5707 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5708 if (status < 0)
5709 goto error;
5710 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5711 if (status < 0)
5712 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005713
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005714 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5715 if (status < 0)
5716 goto error;
5717 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5718 if (status < 0)
5719 goto error;
5720 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5721 if (status < 0)
5722 goto error;
5723 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5724 if (status < 0)
5725 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005726
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005727 /* IQM Impulse Noise Processing Unit */
5728 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5729 if (status < 0)
5730 goto error;
5731 status = write16(state, IQM_CF_DATATH__A, 1000);
5732 if (status < 0)
5733 goto error;
5734 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5735 if (status < 0)
5736 goto error;
5737 status = write16(state, IQM_CF_DET_LCT__A, 0);
5738 if (status < 0)
5739 goto error;
5740 status = write16(state, IQM_CF_WND_LEN__A, 1);
5741 if (status < 0)
5742 goto error;
5743 status = write16(state, IQM_CF_PKDTH__A, 1);
5744 if (status < 0)
5745 goto error;
5746 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5747 if (status < 0)
5748 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005749
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005750 /* turn on IQMAF. Must be done before setAgc**() */
5751 status = SetIqmAf(state, true);
5752 if (status < 0)
5753 goto error;
5754 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5755 if (status < 0)
5756 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005757
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005758 /* IQM will not be reset from here, sync ADC and update/init AGC */
5759 status = ADCSynchronization(state);
5760 if (status < 0)
5761 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005762
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005763 /* Set the FSM step period */
5764 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5765 if (status < 0)
5766 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005767
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005768 /* Halt SCU to enable safe non-atomic accesses */
5769 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5770 if (status < 0)
5771 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005772
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005773 /* No more resets of the IQM, current standard correctly set =>
5774 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005775
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005776 status = InitAGC(state, true);
5777 if (status < 0)
5778 goto error;
5779 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5780 if (status < 0)
5781 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005782
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005783 /* Configure AGC's */
5784 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5785 if (status < 0)
5786 goto error;
5787 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5788 if (status < 0)
5789 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005790
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005791 /* Activate SCU to enable SCU commands */
5792 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5793error:
5794 if (status < 0)
5795 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005796 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005797}
5798
5799static int WriteGPIO(struct drxk_state *state)
5800{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005801 int status;
5802 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005803
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005804 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005805 /* stop lock indicator process */
5806 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5807 if (status < 0)
5808 goto error;
5809
5810 /* Write magic word to enable pdr reg write */
5811 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5812 if (status < 0)
5813 goto error;
5814
5815 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005816 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5817 /* write to io pad configuration register - output mode */
5818 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5819 if (status < 0)
5820 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005821
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005822 /* use corresponding bit in io data output registar */
5823 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5824 if (status < 0)
5825 goto error;
5826 if ((state->m_GPIO & 0x0001) == 0)
5827 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5828 else
5829 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5830 /* write back to io data output register */
5831 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5832 if (status < 0)
5833 goto error;
5834 }
5835 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5836 /* write to io pad configuration register - output mode */
5837 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5838 if (status < 0)
5839 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005840
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005841 /* use corresponding bit in io data output registar */
5842 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5843 if (status < 0)
5844 goto error;
5845 if ((state->m_GPIO & 0x0002) == 0)
5846 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5847 else
5848 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5849 /* write back to io data output register */
5850 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5851 if (status < 0)
5852 goto error;
5853 }
5854 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5855 /* write to io pad configuration register - output mode */
5856 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5857 if (status < 0)
5858 goto error;
5859
5860 /* use corresponding bit in io data output registar */
5861 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5862 if (status < 0)
5863 goto error;
5864 if ((state->m_GPIO & 0x0004) == 0)
5865 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5866 else
5867 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5868 /* write back to io data output register */
5869 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5870 if (status < 0)
5871 goto error;
5872 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005873 }
5874 /* Write magic word to disable pdr reg write */
5875 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5876error:
5877 if (status < 0)
5878 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005879 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005880}
5881
5882static int SwitchAntennaToQAM(struct drxk_state *state)
5883{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005884 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005885 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005886
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005887 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005888
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005889 if (!state->antenna_gpio)
5890 return 0;
5891
5892 gpio_state = state->m_GPIO & state->antenna_gpio;
5893
5894 if (state->antenna_dvbt ^ gpio_state) {
5895 /* Antenna is on DVB-T mode. Switch */
5896 if (state->antenna_dvbt)
5897 state->m_GPIO &= ~state->antenna_gpio;
5898 else
5899 state->m_GPIO |= state->antenna_gpio;
5900 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005901 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005902 if (status < 0)
5903 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005904 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005905}
5906
5907static int SwitchAntennaToDVBT(struct drxk_state *state)
5908{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005909 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005910 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005911
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005912 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005913
5914 if (!state->antenna_gpio)
5915 return 0;
5916
5917 gpio_state = state->m_GPIO & state->antenna_gpio;
5918
5919 if (!(state->antenna_dvbt ^ gpio_state)) {
5920 /* Antenna is on DVB-C mode. Switch */
5921 if (state->antenna_dvbt)
5922 state->m_GPIO |= state->antenna_gpio;
5923 else
5924 state->m_GPIO &= ~state->antenna_gpio;
5925 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005926 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005927 if (status < 0)
5928 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005929 return status;
5930}
5931
5932
5933static int PowerDownDevice(struct drxk_state *state)
5934{
5935 /* Power down to requested mode */
5936 /* Backup some register settings */
5937 /* Set pins with possible pull-ups connected to them in input mode */
5938 /* Analog power down */
5939 /* ADC power down */
5940 /* Power down device */
5941 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005942
5943 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005944 if (state->m_bPDownOpenBridge) {
5945 /* Open I2C bridge before power down of DRXK */
5946 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005947 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005948 goto error;
5949 }
5950 /* driver 0.9.0 */
5951 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005952 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005953 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005954
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005955 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5956 if (status < 0)
5957 goto error;
5958 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5959 if (status < 0)
5960 goto error;
5961 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5962 status = HI_CfgCommand(state);
5963error:
5964 if (status < 0)
5965 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5966
5967 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005968}
5969
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005970static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005971{
5972 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005973 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005974
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005975 dprintk(1, "\n");
5976
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005977 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5978 if (err < 0) {
5979 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005980 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005981 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005982 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005983 return err;
5984 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005985 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005986 release_firmware(fw);
5987 return err;
5988}
5989
5990static int init_drxk(struct drxk_state *state)
5991{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005992 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005993 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005994 u16 driverVersion;
5995
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005996 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005997 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005998 status = PowerUpDevice(state);
5999 if (status < 0)
6000 goto error;
6001 status = DRXX_Open(state);
6002 if (status < 0)
6003 goto error;
6004 /* Soft reset of OFDM-, sys- and osc-clockdomain */
6005 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);
6006 if (status < 0)
6007 goto error;
6008 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6009 if (status < 0)
6010 goto error;
6011 /* TODO is this needed, if yes how much delay in worst case scenario */
6012 msleep(1);
6013 state->m_DRXK_A3_PATCH_CODE = true;
6014 status = GetDeviceCapabilities(state);
6015 if (status < 0)
6016 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006017
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006018 /* Bridge delay, uses oscilator clock */
6019 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6020 /* SDA brdige delay */
6021 state->m_HICfgBridgeDelay =
6022 (u16) ((state->m_oscClockFreq / 1000) *
6023 HI_I2C_BRIDGE_DELAY) / 1000;
6024 /* Clipping */
6025 if (state->m_HICfgBridgeDelay >
6026 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006027 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006028 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6029 }
6030 /* SCL bridge delay, same as SDA for now */
6031 state->m_HICfgBridgeDelay +=
6032 state->m_HICfgBridgeDelay <<
6033 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006034
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006035 status = InitHI(state);
6036 if (status < 0)
6037 goto error;
6038 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006039#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006040 if (!(state->m_DRXK_A1_ROM_CODE)
6041 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006042#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006043 {
6044 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6045 if (status < 0)
6046 goto error;
6047 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006048
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006049 /* disable MPEG port */
6050 status = MPEGTSDisable(state);
6051 if (status < 0)
6052 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006053
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006054 /* Stop AUD and SCU */
6055 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6056 if (status < 0)
6057 goto error;
6058 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6059 if (status < 0)
6060 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006061
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006062 /* enable token-ring bus through OFDM block for possible ucode upload */
6063 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6064 if (status < 0)
6065 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006066
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006067 /* include boot loader section */
6068 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6069 if (status < 0)
6070 goto error;
6071 status = BLChainCmd(state, 0, 6, 100);
6072 if (status < 0)
6073 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006074
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006075 if (!state->microcode_name)
6076 load_microcode(state, "drxk_a3.mc");
6077 else
6078 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006079
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006080 /* disable token-ring bus through OFDM block for possible ucode upload */
6081 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6082 if (status < 0)
6083 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006084
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006085 /* Run SCU for a little while to initialize microcode version numbers */
6086 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6087 if (status < 0)
6088 goto error;
6089 status = DRXX_Open(state);
6090 if (status < 0)
6091 goto error;
6092 /* added for test */
6093 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006094
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006095 powerMode = DRXK_POWER_DOWN_OFDM;
6096 status = CtrlPowerMode(state, &powerMode);
6097 if (status < 0)
6098 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006099
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006100 /* Stamp driver version number in SCU data RAM in BCD code
6101 Done to enable field application engineers to retreive drxdriver version
6102 via I2C from SCU RAM.
6103 Not using SCU command interface for SCU register access since no
6104 microcode may be present.
6105 */
6106 driverVersion =
6107 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6108 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6109 ((DRXK_VERSION_MAJOR % 10) << 4) +
6110 (DRXK_VERSION_MINOR % 10);
6111 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6112 if (status < 0)
6113 goto error;
6114 driverVersion =
6115 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6116 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6117 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6118 (DRXK_VERSION_PATCH % 10);
6119 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6120 if (status < 0)
6121 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006122
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006123 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6124 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6125 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006126
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006127 /* Dirty fix of default values for ROM/PATCH microcode
6128 Dirty because this fix makes it impossible to setup suitable values
6129 before calling DRX_Open. This solution requires changes to RF AGC speed
6130 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006131
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006132 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006133
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006134 /* Reset driver debug flags to 0 */
6135 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6136 if (status < 0)
6137 goto error;
6138 /* driver 0.9.0 */
6139 /* Setup FEC OC:
6140 NOTE: No more full FEC resets allowed afterwards!! */
6141 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6142 if (status < 0)
6143 goto error;
6144 /* MPEGTS functions are still the same */
6145 status = MPEGTSDtoInit(state);
6146 if (status < 0)
6147 goto error;
6148 status = MPEGTSStop(state);
6149 if (status < 0)
6150 goto error;
6151 status = MPEGTSConfigurePolarity(state);
6152 if (status < 0)
6153 goto error;
6154 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6155 if (status < 0)
6156 goto error;
6157 /* added: configure GPIO */
6158 status = WriteGPIO(state);
6159 if (status < 0)
6160 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006161
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006162 state->m_DrxkState = DRXK_STOPPED;
6163
6164 if (state->m_bPowerDown) {
6165 status = PowerDownDevice(state);
6166 if (status < 0)
6167 goto error;
6168 state->m_DrxkState = DRXK_POWERED_DOWN;
6169 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006170 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006171 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006172error:
6173 if (status < 0)
6174 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006175
6176 return 0;
6177}
6178
Oliver Endrissebc7de22011-07-03 13:49:44 -03006179static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006180{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006181 struct drxk_state *state = fe->demodulator_priv;
6182
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006183 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006184 kfree(state);
6185}
6186
Oliver Endrissebc7de22011-07-03 13:49:44 -03006187static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006188{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006189 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006190
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006191 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006192 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006193 return -EBUSY;
6194 SetOperationMode(state, OM_QAM_ITU_A);
6195 return 0;
6196}
6197
Oliver Endrissebc7de22011-07-03 13:49:44 -03006198static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006199{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006200 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006201
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006202 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006203 ShutDown(state);
6204 mutex_unlock(&state->ctlock);
6205 return 0;
6206}
6207
Oliver Endrissebc7de22011-07-03 13:49:44 -03006208static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006209{
6210 struct drxk_state *state = fe->demodulator_priv;
6211
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006212 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006213 return ConfigureI2CBridge(state, enable ? true : false);
6214}
6215
Oliver Endrissebc7de22011-07-03 13:49:44 -03006216static int drxk_set_parameters(struct dvb_frontend *fe,
6217 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006218{
6219 struct drxk_state *state = fe->demodulator_priv;
6220 u32 IF;
6221
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006222 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006223 if (fe->ops.i2c_gate_ctrl)
6224 fe->ops.i2c_gate_ctrl(fe, 1);
6225 if (fe->ops.tuner_ops.set_params)
6226 fe->ops.tuner_ops.set_params(fe, p);
6227 if (fe->ops.i2c_gate_ctrl)
6228 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006229 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006230 fe->ops.tuner_ops.get_frequency(fe, &IF);
6231 Start(state, 0, IF);
6232
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006233 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006234
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006235 return 0;
6236}
6237
Oliver Endrissebc7de22011-07-03 13:49:44 -03006238static int drxk_c_get_frontend(struct dvb_frontend *fe,
6239 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006240{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006241 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006242 return 0;
6243}
6244
6245static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6246{
6247 struct drxk_state *state = fe->demodulator_priv;
6248 u32 stat;
6249
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006250 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006251 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006252 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006253 if (stat == MPEG_LOCK)
6254 *status |= 0x1f;
6255 if (stat == FEC_LOCK)
6256 *status |= 0x0f;
6257 if (stat == DEMOD_LOCK)
6258 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006259 return 0;
6260}
6261
6262static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6263{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006264 dprintk(1, "\n");
6265
Oliver Endrissebc7de22011-07-03 13:49:44 -03006266 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006267 return 0;
6268}
6269
Oliver Endrissebc7de22011-07-03 13:49:44 -03006270static int drxk_read_signal_strength(struct dvb_frontend *fe,
6271 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006272{
6273 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006274 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006275
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006276 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006277 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006278 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006279 return 0;
6280}
6281
6282static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6283{
6284 struct drxk_state *state = fe->demodulator_priv;
6285 s32 snr2;
6286
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006287 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006288 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006289 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006290 return 0;
6291}
6292
6293static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6294{
6295 struct drxk_state *state = fe->demodulator_priv;
6296 u16 err;
6297
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006298 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006299 DVBTQAMGetAccPktErr(state, &err);
6300 *ucblocks = (u32) err;
6301 return 0;
6302}
6303
Oliver Endrissebc7de22011-07-03 13:49:44 -03006304static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6305 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006306{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006307 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006308 sets->min_delay_ms = 3000;
6309 sets->max_drift = 0;
6310 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006311 return 0;
6312}
6313
Oliver Endrissebc7de22011-07-03 13:49:44 -03006314static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006315{
Mauro Carvalho Chehabc4c3a3d2011-07-14 22:23:18 -03006316 /*
6317 * There's nothing to release here, as the state struct
6318 * is already freed by drxk_c_release.
6319 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006320}
6321
Oliver Endrissebc7de22011-07-03 13:49:44 -03006322static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006323{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006324 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006325
6326 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006327 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006328 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006329 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006330 return 0;
6331}
6332
Oliver Endrissebc7de22011-07-03 13:49:44 -03006333static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006334{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006335 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006336
6337 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006338 mutex_unlock(&state->ctlock);
6339 return 0;
6340}
6341
Oliver Endrissebc7de22011-07-03 13:49:44 -03006342static int drxk_t_get_frontend(struct dvb_frontend *fe,
6343 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006344{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006345 dprintk(1, "\n");
6346
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006347 return 0;
6348}
6349
6350static struct dvb_frontend_ops drxk_c_ops = {
6351 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006352 .name = "DRXK DVB-C",
6353 .type = FE_QAM,
6354 .frequency_stepsize = 62500,
6355 .frequency_min = 47000000,
6356 .frequency_max = 862000000,
6357 .symbol_rate_min = 870000,
6358 .symbol_rate_max = 11700000,
6359 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6360 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006361 .release = drxk_c_release,
6362 .init = drxk_c_init,
6363 .sleep = drxk_c_sleep,
6364 .i2c_gate_ctrl = drxk_gate_ctrl,
6365
6366 .set_frontend = drxk_set_parameters,
6367 .get_frontend = drxk_c_get_frontend,
6368 .get_tune_settings = drxk_c_get_tune_settings,
6369
6370 .read_status = drxk_read_status,
6371 .read_ber = drxk_read_ber,
6372 .read_signal_strength = drxk_read_signal_strength,
6373 .read_snr = drxk_read_snr,
6374 .read_ucblocks = drxk_read_ucblocks,
6375};
6376
6377static struct dvb_frontend_ops drxk_t_ops = {
6378 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006379 .name = "DRXK DVB-T",
6380 .type = FE_OFDM,
6381 .frequency_min = 47125000,
6382 .frequency_max = 865000000,
6383 .frequency_stepsize = 166667,
6384 .frequency_tolerance = 0,
6385 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6386 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6387 FE_CAN_FEC_AUTO |
6388 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6389 FE_CAN_QAM_AUTO |
6390 FE_CAN_TRANSMISSION_MODE_AUTO |
6391 FE_CAN_GUARD_INTERVAL_AUTO |
6392 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006393 .release = drxk_t_release,
6394 .init = drxk_t_init,
6395 .sleep = drxk_t_sleep,
6396 .i2c_gate_ctrl = drxk_gate_ctrl,
6397
6398 .set_frontend = drxk_set_parameters,
6399 .get_frontend = drxk_t_get_frontend,
6400
6401 .read_status = drxk_read_status,
6402 .read_ber = drxk_read_ber,
6403 .read_signal_strength = drxk_read_signal_strength,
6404 .read_snr = drxk_read_snr,
6405 .read_ucblocks = drxk_read_ucblocks,
6406};
6407
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006408struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6409 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006410 struct dvb_frontend **fe_t)
6411{
6412 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006413 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006414
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006415 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006416 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006417 if (!state)
6418 return NULL;
6419
Oliver Endrissebc7de22011-07-03 13:49:44 -03006420 state->i2c = i2c;
6421 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006422 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006423 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006424 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006425 state->antenna_gpio = config->antenna_gpio;
6426 state->antenna_dvbt = config->antenna_dvbt;
6427
6428 /* NOTE: as more UIO bits will be used, add them to the mask */
6429 state->UIO_mask = config->antenna_gpio;
6430
6431 /* Default gpio to DVB-C */
6432 if (!state->antenna_dvbt && state->antenna_gpio)
6433 state->m_GPIO |= state->antenna_gpio;
6434 else
6435 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006436
6437 mutex_init(&state->mutex);
6438 mutex_init(&state->ctlock);
6439
Oliver Endrissebc7de22011-07-03 13:49:44 -03006440 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6441 sizeof(struct dvb_frontend_ops));
6442 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6443 sizeof(struct dvb_frontend_ops));
6444 state->c_frontend.demodulator_priv = state;
6445 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006446
6447 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006448 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006449 goto error;
6450 *fe_t = &state->t_frontend;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006451
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006452 return &state->c_frontend;
6453
6454error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006455 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006456 kfree(state);
6457 return NULL;
6458}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006459EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006460
6461MODULE_DESCRIPTION("DRX-K driver");
6462MODULE_AUTHOR("Ralph Metzler");
6463MODULE_LICENSE("GPL");