blob: 5b22c1f9c266adf591b871f10ac2245d6987dbc8 [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 }
1671
1672 /* If already in requested power mode, do nothing */
1673 if (state->m_currentPowerMode == *mode)
1674 return 0;
1675
1676 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001677 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001678 status = PowerUpDevice(state);
1679 if (status < 0)
1680 goto error;
1681 status = DVBTEnableOFDMTokenRing(state, true);
1682 if (status < 0)
1683 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001684 }
1685
1686 if (*mode == DRX_POWER_UP) {
1687 /* Restore analog & pin configuartion */
1688 } else {
1689 /* Power down to requested mode */
1690 /* Backup some register settings */
1691 /* Set pins with possible pull-ups connected
1692 to them in input mode */
1693 /* Analog power down */
1694 /* ADC power down */
1695 /* Power down device */
1696 /* stop all comm_exec */
1697 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001698 switch (state->m_OperationMode) {
1699 case OM_DVBT:
1700 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001701 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001702 goto error;
1703 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001704 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001705 goto error;
1706 break;
1707 case OM_QAM_ITU_A:
1708 case OM_QAM_ITU_C:
1709 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001710 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001711 goto error;
1712 status = PowerDownQAM(state);
1713 if (status < 0)
1714 goto error;
1715 break;
1716 default:
1717 break;
1718 }
1719 status = DVBTEnableOFDMTokenRing(state, false);
1720 if (status < 0)
1721 goto error;
1722 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1723 if (status < 0)
1724 goto error;
1725 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1726 if (status < 0)
1727 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001728
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001729 if (*mode != DRXK_POWER_DOWN_OFDM) {
1730 state->m_HICfgCtrl |=
1731 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1732 status = HI_CfgCommand(state);
1733 if (status < 0)
1734 goto error;
1735 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001736 }
1737 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001738
1739error:
1740 if (status < 0)
1741 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1742
Oliver Endrissebc7de22011-07-03 13:49:44 -03001743 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001744}
1745
1746static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1747{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001748 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001749 u16 cmdResult = 0;
1750 u16 data = 0;
1751 int status;
1752
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001753 dprintk(1, "\n");
1754
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001755 status = read16(state, SCU_COMM_EXEC__A, &data);
1756 if (status < 0)
1757 goto error;
1758 if (data == SCU_COMM_EXEC_ACTIVE) {
1759 /* Send OFDM stop command */
1760 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 -03001761 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001762 goto error;
1763 /* Send OFDM reset command */
1764 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1765 if (status < 0)
1766 goto error;
1767 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001768
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001769 /* Reset datapath for OFDM, processors first */
1770 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1771 if (status < 0)
1772 goto error;
1773 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1774 if (status < 0)
1775 goto error;
1776 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1777 if (status < 0)
1778 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001779
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001780 /* powerdown AFE */
1781 status = SetIqmAf(state, false);
1782 if (status < 0)
1783 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001784
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001785 /* powerdown to OFDM mode */
1786 if (setPowerMode) {
1787 status = CtrlPowerMode(state, &powerMode);
1788 if (status < 0)
1789 goto error;
1790 }
1791error:
1792 if (status < 0)
1793 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001794 return status;
1795}
1796
Oliver Endrissebc7de22011-07-03 13:49:44 -03001797static int SetOperationMode(struct drxk_state *state,
1798 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001799{
1800 int status = 0;
1801
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001802 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001803 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001804 Stop and power down previous standard
1805 TODO investigate total power down instead of partial
1806 power down depending on "previous" standard.
1807 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001808
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001809 /* disable HW lock indicator */
1810 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1811 if (status < 0)
1812 goto error;
1813
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001814 /* Device is already at the required mode */
1815 if (state->m_OperationMode == oMode)
1816 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001817
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001818 switch (state->m_OperationMode) {
1819 /* OM_NONE was added for start up */
1820 case OM_NONE:
1821 break;
1822 case OM_DVBT:
1823 status = MPEGTSStop(state);
1824 if (status < 0)
1825 goto error;
1826 status = PowerDownDVBT(state, true);
1827 if (status < 0)
1828 goto error;
1829 state->m_OperationMode = OM_NONE;
1830 break;
1831 case OM_QAM_ITU_A: /* fallthrough */
1832 case OM_QAM_ITU_C:
1833 status = MPEGTSStop(state);
1834 if (status < 0)
1835 goto error;
1836 status = PowerDownQAM(state);
1837 if (status < 0)
1838 goto error;
1839 state->m_OperationMode = OM_NONE;
1840 break;
1841 case OM_QAM_ITU_B:
1842 default:
1843 status = -EINVAL;
1844 goto error;
1845 }
1846
1847 /*
1848 Power up new standard
1849 */
1850 switch (oMode) {
1851 case OM_DVBT:
1852 state->m_OperationMode = oMode;
1853 status = SetDVBTStandard(state, oMode);
1854 if (status < 0)
1855 goto error;
1856 break;
1857 case OM_QAM_ITU_A: /* fallthrough */
1858 case OM_QAM_ITU_C:
1859 state->m_OperationMode = oMode;
1860 status = SetQAMStandard(state, oMode);
1861 if (status < 0)
1862 goto error;
1863 break;
1864 case OM_QAM_ITU_B:
1865 default:
1866 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001867 }
1868error:
1869 if (status < 0)
1870 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1871 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001872}
1873
1874static int Start(struct drxk_state *state, s32 offsetFreq,
1875 s32 IntermediateFrequency)
1876{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001877 int status = -EINVAL;
1878
1879 u16 IFreqkHz;
1880 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001881
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001882 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001883 if (state->m_DrxkState != DRXK_STOPPED &&
1884 state->m_DrxkState != DRXK_DTV_STARTED)
1885 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001886
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001887 state->m_bMirrorFreqSpect = (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001888
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001889 if (IntermediateFrequency < 0) {
1890 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1891 IntermediateFrequency = -IntermediateFrequency;
1892 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001893
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001894 switch (state->m_OperationMode) {
1895 case OM_QAM_ITU_A:
1896 case OM_QAM_ITU_C:
1897 IFreqkHz = (IntermediateFrequency / 1000);
1898 status = SetQAM(state, IFreqkHz, OffsetkHz);
1899 if (status < 0)
1900 goto error;
1901 state->m_DrxkState = DRXK_DTV_STARTED;
1902 break;
1903 case OM_DVBT:
1904 IFreqkHz = (IntermediateFrequency / 1000);
1905 status = MPEGTSStop(state);
1906 if (status < 0)
1907 goto error;
1908 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1909 if (status < 0)
1910 goto error;
1911 status = DVBTStart(state);
1912 if (status < 0)
1913 goto error;
1914 state->m_DrxkState = DRXK_DTV_STARTED;
1915 break;
1916 default:
1917 break;
1918 }
1919error:
1920 if (status < 0)
1921 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001922 return status;
1923}
1924
1925static int ShutDown(struct drxk_state *state)
1926{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001927 dprintk(1, "\n");
1928
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001929 MPEGTSStop(state);
1930 return 0;
1931}
1932
Oliver Endrissebc7de22011-07-03 13:49:44 -03001933static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1934 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001935{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001936 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001937
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001938 dprintk(1, "\n");
1939
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001940 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001941 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001942
1943 *pLockStatus = NOT_LOCKED;
1944
1945 /* define the SCU command code */
1946 switch (state->m_OperationMode) {
1947 case OM_QAM_ITU_A:
1948 case OM_QAM_ITU_B:
1949 case OM_QAM_ITU_C:
1950 status = GetQAMLockStatus(state, pLockStatus);
1951 break;
1952 case OM_DVBT:
1953 status = GetDVBTLockStatus(state, pLockStatus);
1954 break;
1955 default:
1956 break;
1957 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001958error:
1959 if (status < 0)
1960 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001961 return status;
1962}
1963
1964static int MPEGTSStart(struct drxk_state *state)
1965{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001966 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001967
1968 u16 fecOcSncMode = 0;
1969
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001970 /* Allow OC to sync again */
1971 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1972 if (status < 0)
1973 goto error;
1974 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1975 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1976 if (status < 0)
1977 goto error;
1978 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1979error:
1980 if (status < 0)
1981 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001982 return status;
1983}
1984
1985static int MPEGTSDtoInit(struct drxk_state *state)
1986{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001987 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001988
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001989 dprintk(1, "\n");
1990
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001991 /* Rate integration settings */
1992 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1993 if (status < 0)
1994 goto error;
1995 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1996 if (status < 0)
1997 goto error;
1998 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1999 if (status < 0)
2000 goto error;
2001 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
2002 if (status < 0)
2003 goto error;
2004 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2005 if (status < 0)
2006 goto error;
2007 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2008 if (status < 0)
2009 goto error;
2010 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2011 if (status < 0)
2012 goto error;
2013 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2014 if (status < 0)
2015 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002016
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002017 /* Additional configuration */
2018 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2019 if (status < 0)
2020 goto error;
2021 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2022 if (status < 0)
2023 goto error;
2024 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2025error:
2026 if (status < 0)
2027 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2028
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002029 return status;
2030}
2031
Oliver Endrissebc7de22011-07-03 13:49:44 -03002032static int MPEGTSDtoSetup(struct drxk_state *state,
2033 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002034{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002035 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002036
Oliver Endrissebc7de22011-07-03 13:49:44 -03002037 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2038 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2039 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2040 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2041 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2042 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2043 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002044 u16 fecOcTmdMode = 0;
2045 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002046 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002047 bool staticCLK = false;
2048
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002049 dprintk(1, "\n");
2050
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002051 /* Check insertion of the Reed-Solomon parity bytes */
2052 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2053 if (status < 0)
2054 goto error;
2055 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2056 if (status < 0)
2057 goto error;
2058 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2059 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2060 if (state->m_insertRSByte == true) {
2061 /* enable parity symbol forward */
2062 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2063 /* MVAL disable during parity bytes */
2064 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2065 /* TS burst length to 204 */
2066 fecOcDtoBurstLen = 204;
2067 }
2068
2069 /* Check serial or parrallel output */
2070 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2071 if (state->m_enableParallel == false) {
2072 /* MPEG data output is serial -> set ipr_mode[0] */
2073 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2074 }
2075
2076 switch (oMode) {
2077 case OM_DVBT:
2078 maxBitRate = state->m_DVBTBitrate;
2079 fecOcTmdMode = 3;
2080 fecOcRcnCtlRate = 0xC00000;
2081 staticCLK = state->m_DVBTStaticCLK;
2082 break;
2083 case OM_QAM_ITU_A: /* fallthrough */
2084 case OM_QAM_ITU_C:
2085 fecOcTmdMode = 0x0004;
2086 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2087 maxBitRate = state->m_DVBCBitrate;
2088 staticCLK = state->m_DVBCStaticCLK;
2089 break;
2090 default:
2091 status = -EINVAL;
2092 } /* switch (standard) */
2093 if (status < 0)
2094 goto error;
2095
2096 /* Configure DTO's */
2097 if (staticCLK) {
2098 u32 bitRate = 0;
2099
2100 /* Rational DTO for MCLK source (static MCLK rate),
2101 Dynamic DTO for optimal grouping
2102 (avoid intra-packet gaps),
2103 DTO offset enable to sync TS burst with MSTRT */
2104 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2105 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2106 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2107 FEC_OC_FCT_MODE_VIRT_ENA__M);
2108
2109 /* Check user defined bitrate */
2110 bitRate = maxBitRate;
2111 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2112 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002113 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002114 /* Rational DTO period:
2115 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002116
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002117 Result should be floored,
2118 to make sure >= requested bitrate
2119 */
2120 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2121 * 1000) / bitRate);
2122 if (fecOcDtoPeriod <= 2)
2123 fecOcDtoPeriod = 0;
2124 else
2125 fecOcDtoPeriod -= 2;
2126 fecOcTmdIntUpdRate = 8;
2127 } else {
2128 /* (commonAttr->staticCLK == false) => dynamic mode */
2129 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2130 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2131 fecOcTmdIntUpdRate = 5;
2132 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002133
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002134 /* Write appropriate registers with requested configuration */
2135 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2136 if (status < 0)
2137 goto error;
2138 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2139 if (status < 0)
2140 goto error;
2141 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2142 if (status < 0)
2143 goto error;
2144 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2145 if (status < 0)
2146 goto error;
2147 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2148 if (status < 0)
2149 goto error;
2150 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2151 if (status < 0)
2152 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002153
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002154 /* Rate integration settings */
2155 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2156 if (status < 0)
2157 goto error;
2158 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2159 if (status < 0)
2160 goto error;
2161 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2162error:
2163 if (status < 0)
2164 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002165 return status;
2166}
2167
2168static int MPEGTSConfigurePolarity(struct drxk_state *state)
2169{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002170 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002171
2172 /* Data mask for the output data byte */
2173 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002174 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2175 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2176 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2177 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002178
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002179 dprintk(1, "\n");
2180
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002181 /* Control selective inversion of output bits */
2182 fecOcRegIprInvert &= (~(InvertDataMask));
2183 if (state->m_invertDATA == true)
2184 fecOcRegIprInvert |= InvertDataMask;
2185 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2186 if (state->m_invertERR == true)
2187 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2188 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2189 if (state->m_invertSTR == true)
2190 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2191 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2192 if (state->m_invertVAL == true)
2193 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2194 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2195 if (state->m_invertCLK == true)
2196 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002197
2198 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002199}
2200
2201#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2202
2203static int SetAgcRf(struct drxk_state *state,
2204 struct SCfgAgc *pAgcCfg, bool isDTV)
2205{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002206 int status = -EINVAL;
2207 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002208 struct SCfgAgc *pIfAgcSettings;
2209
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002210 dprintk(1, "\n");
2211
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002212 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002213 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002214
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002215 switch (pAgcCfg->ctrlMode) {
2216 case DRXK_AGC_CTRL_AUTO:
2217 /* Enable RF AGC DAC */
2218 status = read16(state, IQM_AF_STDBY__A, &data);
2219 if (status < 0)
2220 goto error;
2221 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2222 status = write16(state, IQM_AF_STDBY__A, data);
2223 if (status < 0)
2224 goto error;
2225 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2226 if (status < 0)
2227 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002228
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002229 /* Enable SCU RF AGC loop */
2230 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002231
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002232 /* Polarity */
2233 if (state->m_RfAgcPol)
2234 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2235 else
2236 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2237 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2238 if (status < 0)
2239 goto error;
2240
2241 /* Set speed (using complementary reduction value) */
2242 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2243 if (status < 0)
2244 goto error;
2245
2246 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2247 data |= (~(pAgcCfg->speed <<
2248 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2249 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2250
2251 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2252 if (status < 0)
2253 goto error;
2254
2255 if (IsDVBT(state))
2256 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2257 else if (IsQAM(state))
2258 pIfAgcSettings = &state->m_qamIfAgcCfg;
2259 else
2260 pIfAgcSettings = &state->m_atvIfAgcCfg;
2261 if (pIfAgcSettings == NULL) {
2262 status = -EINVAL;
2263 goto error;
2264 }
2265
2266 /* Set TOP, only if IF-AGC is in AUTO mode */
2267 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2268 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002269 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002270 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002271
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002272 /* Cut-Off current */
2273 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2274 if (status < 0)
2275 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002276
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002277 /* Max. output level */
2278 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2279 if (status < 0)
2280 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002281
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002282 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002283
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002284 case DRXK_AGC_CTRL_USER:
2285 /* Enable RF AGC DAC */
2286 status = read16(state, IQM_AF_STDBY__A, &data);
2287 if (status < 0)
2288 goto error;
2289 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2290 status = write16(state, IQM_AF_STDBY__A, data);
2291 if (status < 0)
2292 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002293
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002294 /* Disable SCU RF AGC loop */
2295 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2296 if (status < 0)
2297 goto error;
2298 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2299 if (state->m_RfAgcPol)
2300 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2301 else
2302 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2303 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2304 if (status < 0)
2305 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002306
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002307 /* SCU c.o.c. to 0, enabling full control range */
2308 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2309 if (status < 0)
2310 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002311
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002312 /* Write value to output pin */
2313 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2314 if (status < 0)
2315 goto error;
2316 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002317
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002318 case DRXK_AGC_CTRL_OFF:
2319 /* Disable RF AGC DAC */
2320 status = read16(state, IQM_AF_STDBY__A, &data);
2321 if (status < 0)
2322 goto error;
2323 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2324 status = write16(state, IQM_AF_STDBY__A, data);
2325 if (status < 0)
2326 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002327
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002328 /* Disable SCU RF AGC loop */
2329 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2330 if (status < 0)
2331 goto error;
2332 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2333 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2334 if (status < 0)
2335 goto error;
2336 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002337
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002338 default:
2339 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002340
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002341 }
2342error:
2343 if (status < 0)
2344 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002345 return status;
2346}
2347
2348#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2349
Oliver Endrissebc7de22011-07-03 13:49:44 -03002350static int SetAgcIf(struct drxk_state *state,
2351 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002352{
2353 u16 data = 0;
2354 int status = 0;
2355 struct SCfgAgc *pRfAgcSettings;
2356
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002357 dprintk(1, "\n");
2358
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002359 switch (pAgcCfg->ctrlMode) {
2360 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002361
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002362 /* Enable IF AGC DAC */
2363 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002364 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002365 goto error;
2366 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2367 status = write16(state, IQM_AF_STDBY__A, data);
2368 if (status < 0)
2369 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002370
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002371 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2372 if (status < 0)
2373 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002374
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002375 /* Enable SCU IF AGC loop */
2376 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2377
2378 /* Polarity */
2379 if (state->m_IfAgcPol)
2380 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2381 else
2382 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2383 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2384 if (status < 0)
2385 goto error;
2386
2387 /* Set speed (using complementary reduction value) */
2388 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2389 if (status < 0)
2390 goto error;
2391 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2392 data |= (~(pAgcCfg->speed <<
2393 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2394 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2395
2396 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2397 if (status < 0)
2398 goto error;
2399
2400 if (IsQAM(state))
2401 pRfAgcSettings = &state->m_qamRfAgcCfg;
2402 else
2403 pRfAgcSettings = &state->m_atvRfAgcCfg;
2404 if (pRfAgcSettings == NULL)
2405 return -1;
2406 /* Restore TOP */
2407 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2408 if (status < 0)
2409 goto error;
2410 break;
2411
2412 case DRXK_AGC_CTRL_USER:
2413
2414 /* Enable IF AGC DAC */
2415 status = read16(state, IQM_AF_STDBY__A, &data);
2416 if (status < 0)
2417 goto error;
2418 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2419 status = write16(state, IQM_AF_STDBY__A, data);
2420 if (status < 0)
2421 goto error;
2422
2423 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2424 if (status < 0)
2425 goto error;
2426
2427 /* Disable SCU IF AGC loop */
2428 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2429
2430 /* Polarity */
2431 if (state->m_IfAgcPol)
2432 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2433 else
2434 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2435 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2436 if (status < 0)
2437 goto error;
2438
2439 /* Write value to output pin */
2440 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2441 if (status < 0)
2442 goto error;
2443 break;
2444
2445 case DRXK_AGC_CTRL_OFF:
2446
2447 /* Disable If AGC DAC */
2448 status = read16(state, IQM_AF_STDBY__A, &data);
2449 if (status < 0)
2450 goto error;
2451 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2452 status = write16(state, IQM_AF_STDBY__A, data);
2453 if (status < 0)
2454 goto error;
2455
2456 /* Disable SCU IF AGC loop */
2457 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2458 if (status < 0)
2459 goto error;
2460 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2461 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2462 if (status < 0)
2463 goto error;
2464 break;
2465 } /* switch (agcSettingsIf->ctrlMode) */
2466
2467 /* always set the top to support
2468 configurations without if-loop */
2469 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2470error:
2471 if (status < 0)
2472 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002473 return status;
2474}
2475
2476static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2477{
2478 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002479 int status;
2480 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002481
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002482 dprintk(1, "\n");
2483
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002484 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2485 if (status < 0) {
2486 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2487 return status;
2488 }
2489
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002490 *pValue = 0;
2491
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002492 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2493 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2494 if (Level < 14000)
2495 *pValue = (14000 - Level) / 4;
2496 else
2497 *pValue = 0;
2498
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002499 return status;
2500}
2501
Oliver Endrissebc7de22011-07-03 13:49:44 -03002502static int GetQAMSignalToNoise(struct drxk_state *state,
2503 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002504{
2505 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002506 u16 qamSlErrPower = 0; /* accum. error between
2507 raw and sliced symbols */
2508 u32 qamSlSigPower = 0; /* used for MER, depends of
2509 QAM constellation */
2510 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002511
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002512 dprintk(1, "\n");
2513
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002514 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002515
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002516 /* get the register value needed for MER */
2517 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2518 if (status < 0) {
2519 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2520 return -EINVAL;
2521 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002522
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002523 switch (state->param.u.qam.modulation) {
2524 case QAM_16:
2525 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2526 break;
2527 case QAM_32:
2528 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2529 break;
2530 case QAM_64:
2531 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2532 break;
2533 case QAM_128:
2534 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2535 break;
2536 default:
2537 case QAM_256:
2538 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2539 break;
2540 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002541
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002542 if (qamSlErrPower > 0) {
2543 qamSlMer = Log10Times100(qamSlSigPower) -
2544 Log10Times100((u32) qamSlErrPower);
2545 }
2546 *pSignalToNoise = qamSlMer;
2547
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002548 return status;
2549}
2550
Oliver Endrissebc7de22011-07-03 13:49:44 -03002551static int GetDVBTSignalToNoise(struct drxk_state *state,
2552 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002553{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002554 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002555 u16 regData = 0;
2556 u32 EqRegTdSqrErrI = 0;
2557 u32 EqRegTdSqrErrQ = 0;
2558 u16 EqRegTdSqrErrExp = 0;
2559 u16 EqRegTdTpsPwrOfs = 0;
2560 u16 EqRegTdReqSmbCnt = 0;
2561 u32 tpsCnt = 0;
2562 u32 SqrErrIQ = 0;
2563 u32 a = 0;
2564 u32 b = 0;
2565 u32 c = 0;
2566 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002567 u16 transmissionParams = 0;
2568
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002569 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002570
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002571 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2572 if (status < 0)
2573 goto error;
2574 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2575 if (status < 0)
2576 goto error;
2577 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2578 if (status < 0)
2579 goto error;
2580 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2581 if (status < 0)
2582 goto error;
2583 /* Extend SQR_ERR_I operational range */
2584 EqRegTdSqrErrI = (u32) regData;
2585 if ((EqRegTdSqrErrExp > 11) &&
2586 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2587 EqRegTdSqrErrI += 0x00010000UL;
2588 }
2589 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2590 if (status < 0)
2591 goto error;
2592 /* Extend SQR_ERR_Q operational range */
2593 EqRegTdSqrErrQ = (u32) regData;
2594 if ((EqRegTdSqrErrExp > 11) &&
2595 (EqRegTdSqrErrQ < 0x00000FFFUL))
2596 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002597
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002598 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2599 if (status < 0)
2600 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002601
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002602 /* Check input data for MER */
2603
2604 /* MER calculation (in 0.1 dB) without math.h */
2605 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2606 iMER = 0;
2607 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2608 /* No error at all, this must be the HW reset value
2609 * Apparently no first measurement yet
2610 * Set MER to 0.0 */
2611 iMER = 0;
2612 } else {
2613 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2614 EqRegTdSqrErrExp;
2615 if ((transmissionParams &
2616 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2617 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2618 tpsCnt = 17;
2619 else
2620 tpsCnt = 68;
2621
2622 /* IMER = 100 * log10 (x)
2623 where x = (EqRegTdTpsPwrOfs^2 *
2624 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2625
2626 => IMER = a + b -c
2627 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2628 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2629 c = 100 * log10 (SqrErrIQ)
2630 */
2631
2632 /* log(x) x = 9bits * 9bits->18 bits */
2633 a = Log10Times100(EqRegTdTpsPwrOfs *
2634 EqRegTdTpsPwrOfs);
2635 /* log(x) x = 16bits * 7bits->23 bits */
2636 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2637 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2638 c = Log10Times100(SqrErrIQ);
2639
2640 iMER = a + b;
2641 /* No negative MER, clip to zero */
2642 if (iMER > c)
2643 iMER -= c;
2644 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002645 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002646 }
2647 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002648
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002649error:
2650 if (status < 0)
2651 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002652 return status;
2653}
2654
2655static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2656{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002657 dprintk(1, "\n");
2658
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002659 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002660 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002661 case OM_DVBT:
2662 return GetDVBTSignalToNoise(state, pSignalToNoise);
2663 case OM_QAM_ITU_A:
2664 case OM_QAM_ITU_C:
2665 return GetQAMSignalToNoise(state, pSignalToNoise);
2666 default:
2667 break;
2668 }
2669 return 0;
2670}
2671
2672#if 0
2673static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2674{
2675 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2676 int status = 0;
2677
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002678 dprintk(1, "\n");
2679
Oliver Endrissebc7de22011-07-03 13:49:44 -03002680 static s32 QE_SN[] = {
2681 51, /* QPSK 1/2 */
2682 69, /* QPSK 2/3 */
2683 79, /* QPSK 3/4 */
2684 89, /* QPSK 5/6 */
2685 97, /* QPSK 7/8 */
2686 108, /* 16-QAM 1/2 */
2687 131, /* 16-QAM 2/3 */
2688 146, /* 16-QAM 3/4 */
2689 156, /* 16-QAM 5/6 */
2690 160, /* 16-QAM 7/8 */
2691 165, /* 64-QAM 1/2 */
2692 187, /* 64-QAM 2/3 */
2693 202, /* 64-QAM 3/4 */
2694 216, /* 64-QAM 5/6 */
2695 225, /* 64-QAM 7/8 */
2696 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002697
2698 *pQuality = 0;
2699
2700 do {
2701 s32 SignalToNoise = 0;
2702 u16 Constellation = 0;
2703 u16 CodeRate = 0;
2704 u32 SignalToNoiseRel;
2705 u32 BERQuality;
2706
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002707 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2708 if (status < 0)
2709 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002710 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002711 if (status < 0)
2712 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002713 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2714
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002715 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002716 if (status < 0)
2717 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002718 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2719
2720 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2721 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2722 break;
2723 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002724 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002725 BERQuality = 100;
2726
Oliver Endrissebc7de22011-07-03 13:49:44 -03002727 if (SignalToNoiseRel < -70)
2728 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002729 else if (SignalToNoiseRel < 30)
2730 *pQuality = ((SignalToNoiseRel + 70) *
2731 BERQuality) / 100;
2732 else
2733 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002734 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002735 return 0;
2736};
2737
Oliver Endrissebc7de22011-07-03 13:49:44 -03002738static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002739{
2740 int status = 0;
2741 *pQuality = 0;
2742
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002743 dprintk(1, "\n");
2744
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002745 do {
2746 u32 SignalToNoise = 0;
2747 u32 BERQuality = 100;
2748 u32 SignalToNoiseRel = 0;
2749
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002750 status = GetQAMSignalToNoise(state, &SignalToNoise);
2751 if (status < 0)
2752 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002753
Oliver Endrissebc7de22011-07-03 13:49:44 -03002754 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002755 case QAM_16:
2756 SignalToNoiseRel = SignalToNoise - 200;
2757 break;
2758 case QAM_32:
2759 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002760 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002761 case QAM_64:
2762 SignalToNoiseRel = SignalToNoise - 260;
2763 break;
2764 case QAM_128:
2765 SignalToNoiseRel = SignalToNoise - 290;
2766 break;
2767 default:
2768 case QAM_256:
2769 SignalToNoiseRel = SignalToNoise - 320;
2770 break;
2771 }
2772
2773 if (SignalToNoiseRel < -70)
2774 *pQuality = 0;
2775 else if (SignalToNoiseRel < 30)
2776 *pQuality = ((SignalToNoiseRel + 70) *
2777 BERQuality) / 100;
2778 else
2779 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002780 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002781
2782 return status;
2783}
2784
2785static int GetQuality(struct drxk_state *state, s32 *pQuality)
2786{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002787 dprintk(1, "\n");
2788
Oliver Endrissebc7de22011-07-03 13:49:44 -03002789 switch (state->m_OperationMode) {
2790 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002791 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002792 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002793 return GetDVBCQuality(state, pQuality);
2794 default:
2795 break;
2796 }
2797
2798 return 0;
2799}
2800#endif
2801
2802/* Free data ram in SIO HI */
2803#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2804#define SIO_HI_RA_RAM_USR_END__A 0x420060
2805
2806#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2807#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2808#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2809#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2810
2811#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2812#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2813#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2814
2815static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2816{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002817 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002818
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002819 dprintk(1, "\n");
2820
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002821 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002822 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002823 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002824 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002825
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002826 if (state->no_i2c_bridge)
2827 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002828
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002829 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2830 if (status < 0)
2831 goto error;
2832 if (bEnableBridge) {
2833 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 -03002834 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002835 goto error;
2836 } else {
2837 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2838 if (status < 0)
2839 goto error;
2840 }
2841
2842 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2843
2844error:
2845 if (status < 0)
2846 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002847 return status;
2848}
2849
Oliver Endrissebc7de22011-07-03 13:49:44 -03002850static int SetPreSaw(struct drxk_state *state,
2851 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002852{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002853 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002854
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002855 dprintk(1, "\n");
2856
Oliver Endrissebc7de22011-07-03 13:49:44 -03002857 if ((pPreSawCfg == NULL)
2858 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002859 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002860
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002861 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002862error:
2863 if (status < 0)
2864 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002865 return status;
2866}
2867
2868static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002869 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002870{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002871 u16 blStatus = 0;
2872 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2873 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2874 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002875 unsigned long end;
2876
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002877 dprintk(1, "\n");
2878
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002879 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002880 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2881 if (status < 0)
2882 goto error;
2883 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2884 if (status < 0)
2885 goto error;
2886 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2887 if (status < 0)
2888 goto error;
2889 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2890 if (status < 0)
2891 goto error;
2892 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2893 if (status < 0)
2894 goto error;
2895 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2896 if (status < 0)
2897 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002898
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002899 end = jiffies + msecs_to_jiffies(timeOut);
2900 do {
2901 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2902 if (status < 0)
2903 goto error;
2904 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2905 if (blStatus == 0x1) {
2906 printk(KERN_ERR "drxk: SIO not ready\n");
2907 status = -EINVAL;
2908 goto error2;
2909 }
2910error:
2911 if (status < 0)
2912 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2913error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002914 mutex_unlock(&state->mutex);
2915 return status;
2916
2917}
2918
Oliver Endrissebc7de22011-07-03 13:49:44 -03002919static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002920{
2921 u16 data = 0;
2922 int status;
2923
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002924 dprintk(1, "\n");
2925
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002926 /* Start measurement */
2927 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2928 if (status < 0)
2929 goto error;
2930 status = write16(state, IQM_AF_START_LOCK__A, 1);
2931 if (status < 0)
2932 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002933
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002934 *count = 0;
2935 status = read16(state, IQM_AF_PHASE0__A, &data);
2936 if (status < 0)
2937 goto error;
2938 if (data == 127)
2939 *count = *count + 1;
2940 status = read16(state, IQM_AF_PHASE1__A, &data);
2941 if (status < 0)
2942 goto error;
2943 if (data == 127)
2944 *count = *count + 1;
2945 status = read16(state, IQM_AF_PHASE2__A, &data);
2946 if (status < 0)
2947 goto error;
2948 if (data == 127)
2949 *count = *count + 1;
2950
2951error:
2952 if (status < 0)
2953 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002954 return status;
2955}
2956
2957static int ADCSynchronization(struct drxk_state *state)
2958{
2959 u16 count = 0;
2960 int status;
2961
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002962 dprintk(1, "\n");
2963
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002964 status = ADCSyncMeasurement(state, &count);
2965 if (status < 0)
2966 goto error;
2967
2968 if (count == 1) {
2969 /* Try sampling on a diffrent edge */
2970 u16 clkNeg = 0;
2971
2972 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2973 if (status < 0)
2974 goto error;
2975 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2976 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2977 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2978 clkNeg |=
2979 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2980 } else {
2981 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2982 clkNeg |=
2983 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2984 }
2985 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2986 if (status < 0)
2987 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002988 status = ADCSyncMeasurement(state, &count);
2989 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002990 goto error;
2991 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002992
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002993 if (count < 2)
2994 status = -EINVAL;
2995error:
2996 if (status < 0)
2997 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002998 return status;
2999}
3000
3001static int SetFrequencyShifter(struct drxk_state *state,
3002 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003003 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003004{
3005 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003006 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003007 u32 fmFrequencyShift = 0;
3008 bool tunerMirror = !state->m_bMirrorFreqSpect;
3009 u32 adcFreq;
3010 bool adcFlip;
3011 int status;
3012 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003013 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003014 u32 frequencyShift;
3015 bool imageToSelect;
3016
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003017 dprintk(1, "\n");
3018
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003019 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003020 Program frequency shifter
3021 No need to account for mirroring on RF
3022 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003023 if (isDTV) {
3024 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3025 (state->m_OperationMode == OM_QAM_ITU_C) ||
3026 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003027 selectPosImage = true;
3028 else
3029 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003030 }
3031 if (tunerMirror)
3032 /* tuner doesn't mirror */
3033 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003034 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003035 else
3036 /* tuner mirrors */
3037 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003038 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003039 if (ifFreqActual > samplingFrequency / 2) {
3040 /* adc mirrors */
3041 adcFreq = samplingFrequency - ifFreqActual;
3042 adcFlip = true;
3043 } else {
3044 /* adc doesn't mirror */
3045 adcFreq = ifFreqActual;
3046 adcFlip = false;
3047 }
3048
3049 frequencyShift = adcFreq;
3050 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003051 adcFlip ^ selectPosImage;
3052 state->m_IqmFsRateOfs =
3053 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003054
3055 if (imageToSelect)
3056 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3057
3058 /* Program frequency shifter with tuner offset compensation */
3059 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003060 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3061 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003062 if (status < 0)
3063 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003064 return status;
3065}
3066
3067static int InitAGC(struct drxk_state *state, bool isDTV)
3068{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003069 u16 ingainTgt = 0;
3070 u16 ingainTgtMin = 0;
3071 u16 ingainTgtMax = 0;
3072 u16 clpCyclen = 0;
3073 u16 clpSumMin = 0;
3074 u16 clpDirTo = 0;
3075 u16 snsSumMin = 0;
3076 u16 snsSumMax = 0;
3077 u16 clpSumMax = 0;
3078 u16 snsDirTo = 0;
3079 u16 kiInnergainMin = 0;
3080 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003081 u16 ifIaccuHiTgtMin = 0;
3082 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003083 u16 data = 0;
3084 u16 fastClpCtrlDelay = 0;
3085 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003086 int status = 0;
3087
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003088 dprintk(1, "\n");
3089
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003090 /* Common settings */
3091 snsSumMax = 1023;
3092 ifIaccuHiTgtMin = 2047;
3093 clpCyclen = 500;
3094 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003095
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003096 /* AGCInit() not available for DVBT; init done in microcode */
3097 if (!IsQAM(state)) {
3098 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3099 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003100 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003101
3102 /* FIXME: Analog TV AGC require different settings */
3103
3104 /* Standard specific settings */
3105 clpSumMin = 8;
3106 clpDirTo = (u16) -9;
3107 clpCtrlMode = 0;
3108 snsSumMin = 8;
3109 snsDirTo = (u16) -9;
3110 kiInnergainMin = (u16) -1030;
3111 ifIaccuHiTgtMax = 0x2380;
3112 ifIaccuHiTgt = 0x2380;
3113 ingainTgtMin = 0x0511;
3114 ingainTgt = 0x0511;
3115 ingainTgtMax = 5119;
3116 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3117
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003118 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3119 if (status < 0)
3120 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003121
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003122 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3123 if (status < 0)
3124 goto error;
3125 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3126 if (status < 0)
3127 goto error;
3128 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3129 if (status < 0)
3130 goto error;
3131 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3132 if (status < 0)
3133 goto error;
3134 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3135 if (status < 0)
3136 goto error;
3137 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3138 if (status < 0)
3139 goto error;
3140 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3141 if (status < 0)
3142 goto error;
3143 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3144 if (status < 0)
3145 goto error;
3146 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3147 if (status < 0)
3148 goto error;
3149 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3150 if (status < 0)
3151 goto error;
3152 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3153 if (status < 0)
3154 goto error;
3155 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3156 if (status < 0)
3157 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003158
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003159 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3160 if (status < 0)
3161 goto error;
3162 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3163 if (status < 0)
3164 goto error;
3165 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3166 if (status < 0)
3167 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003168
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003169 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3170 if (status < 0)
3171 goto error;
3172 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3173 if (status < 0)
3174 goto error;
3175 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3176 if (status < 0)
3177 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003178
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003179 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3180 if (status < 0)
3181 goto error;
3182 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3183 if (status < 0)
3184 goto error;
3185 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3186 if (status < 0)
3187 goto error;
3188 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3189 if (status < 0)
3190 goto error;
3191 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3192 if (status < 0)
3193 goto error;
3194 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3195 if (status < 0)
3196 goto error;
3197 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3198 if (status < 0)
3199 goto error;
3200 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3201 if (status < 0)
3202 goto error;
3203 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3204 if (status < 0)
3205 goto error;
3206 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3207 if (status < 0)
3208 goto error;
3209 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3210 if (status < 0)
3211 goto error;
3212 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3213 if (status < 0)
3214 goto error;
3215 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3216 if (status < 0)
3217 goto error;
3218 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3219 if (status < 0)
3220 goto error;
3221 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3222 if (status < 0)
3223 goto error;
3224 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3225 if (status < 0)
3226 goto error;
3227 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3228 if (status < 0)
3229 goto error;
3230 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3231 if (status < 0)
3232 goto error;
3233 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3234 if (status < 0)
3235 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003236
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003237 /* Initialize inner-loop KI gain factors */
3238 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3239 if (status < 0)
3240 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003241
3242 data = 0x0657;
3243 data &= ~SCU_RAM_AGC_KI_RF__M;
3244 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3245 data &= ~SCU_RAM_AGC_KI_IF__M;
3246 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3247
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003248 status = write16(state, SCU_RAM_AGC_KI__A, data);
3249error:
3250 if (status < 0)
3251 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003252 return status;
3253}
3254
Oliver Endrissebc7de22011-07-03 13:49:44 -03003255static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003256{
3257 int status;
3258
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003259 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003260 if (packetErr == NULL)
3261 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3262 else
3263 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3264 if (status < 0)
3265 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003266 return status;
3267}
3268
3269static int DVBTScCommand(struct drxk_state *state,
3270 u16 cmd, u16 subcmd,
3271 u16 param0, u16 param1, u16 param2,
3272 u16 param3, u16 param4)
3273{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003274 u16 curCmd = 0;
3275 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003276 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003277 u16 scExec = 0;
3278 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003279
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003280 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003281 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003282 if (scExec != 1) {
3283 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003284 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003285 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003286 if (status < 0)
3287 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003288
3289 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003290 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003291 do {
3292 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003293 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003294 retryCnt++;
3295 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003296 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3297 goto error;
3298
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003299 /* Write sub-command */
3300 switch (cmd) {
3301 /* All commands using sub-cmd */
3302 case OFDM_SC_RA_RAM_CMD_PROC_START:
3303 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3304 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003305 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3306 if (status < 0)
3307 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003308 break;
3309 default:
3310 /* Do nothing */
3311 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003312 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003313
3314 /* Write needed parameters and the command */
3315 switch (cmd) {
3316 /* All commands using 5 parameters */
3317 /* All commands using 4 parameters */
3318 /* All commands using 3 parameters */
3319 /* All commands using 2 parameters */
3320 case OFDM_SC_RA_RAM_CMD_PROC_START:
3321 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3322 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003323 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003324 /* All commands using 1 parameters */
3325 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3326 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003327 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003328 /* All commands using 0 parameters */
3329 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3330 case OFDM_SC_RA_RAM_CMD_NULL:
3331 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003332 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003333 break;
3334 default:
3335 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003336 status = -EINVAL;
3337 }
3338 if (status < 0)
3339 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003340
3341 /* Wait until sc is ready processing command */
3342 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003343 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003344 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003345 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003346 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003347 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003348 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3349 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003350
3351 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003352 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003353 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003354 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003355 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003356 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003357 if (status < 0)
3358 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003359
3360 /* Retreive results parameters from SC */
3361 switch (cmd) {
3362 /* All commands yielding 5 results */
3363 /* All commands yielding 4 results */
3364 /* All commands yielding 3 results */
3365 /* All commands yielding 2 results */
3366 /* All commands yielding 1 result */
3367 case OFDM_SC_RA_RAM_CMD_USER_IO:
3368 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003369 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003370 /* All commands yielding 0 results */
3371 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3372 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3373 case OFDM_SC_RA_RAM_CMD_PROC_START:
3374 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3375 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3376 case OFDM_SC_RA_RAM_CMD_NULL:
3377 break;
3378 default:
3379 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003380 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003381 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003382 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003383error:
3384 if (status < 0)
3385 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003386 return status;
3387}
3388
Oliver Endrissebc7de22011-07-03 13:49:44 -03003389static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003390{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003391 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003392 int status;
3393
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003394 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003395 status = CtrlPowerMode(state, &powerMode);
3396 if (status < 0)
3397 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003398 return status;
3399}
3400
Oliver Endrissebc7de22011-07-03 13:49:44 -03003401static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003402{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003403 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003404
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003405 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003406 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003407 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003408 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003409 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003410 if (status < 0)
3411 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003412 return status;
3413}
3414
3415#define DEFAULT_FR_THRES_8K 4000
3416static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3417{
3418
3419 int status;
3420
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003421 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003422 if (*enabled == true) {
3423 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003424 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003425 DEFAULT_FR_THRES_8K);
3426 } else {
3427 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003428 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003429 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003430 if (status < 0)
3431 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003432
3433 return status;
3434}
3435
3436static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3437 struct DRXKCfgDvbtEchoThres_t *echoThres)
3438{
3439 u16 data = 0;
3440 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003441
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003442 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003443 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3444 if (status < 0)
3445 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003446
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003447 switch (echoThres->fftMode) {
3448 case DRX_FFTMODE_2K:
3449 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3450 data |= ((echoThres->threshold <<
3451 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3452 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003453 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003454 case DRX_FFTMODE_8K:
3455 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3456 data |= ((echoThres->threshold <<
3457 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3458 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003459 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003460 default:
3461 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003462 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003463
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003464 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3465error:
3466 if (status < 0)
3467 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003468 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003469}
3470
3471static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003472 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003473{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003474 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003475
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003476 dprintk(1, "\n");
3477
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003478 switch (*speed) {
3479 case DRXK_DVBT_SQI_SPEED_FAST:
3480 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3481 case DRXK_DVBT_SQI_SPEED_SLOW:
3482 break;
3483 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003484 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003485 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003486 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003487 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003488error:
3489 if (status < 0)
3490 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003491 return status;
3492}
3493
3494/*============================================================================*/
3495
3496/**
3497* \brief Activate DVBT specific presets
3498* \param demod instance of demodulator.
3499* \return DRXStatus_t.
3500*
3501* Called in DVBTSetStandard
3502*
3503*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003504static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003505{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003506 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003507 bool setincenable = false;
3508 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003509
Oliver Endrissebc7de22011-07-03 13:49:44 -03003510 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3511 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003512
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003513 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003514 status = DVBTCtrlSetIncEnable(state, &setincenable);
3515 if (status < 0)
3516 goto error;
3517 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3518 if (status < 0)
3519 goto error;
3520 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3521 if (status < 0)
3522 goto error;
3523 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3524 if (status < 0)
3525 goto error;
3526 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3527error:
3528 if (status < 0)
3529 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003530 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003531}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003532
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003533/*============================================================================*/
3534
3535/**
3536* \brief Initialize channelswitch-independent settings for DVBT.
3537* \param demod instance of demodulator.
3538* \return DRXStatus_t.
3539*
3540* For ROM code channel filter taps are loaded from the bootloader. For microcode
3541* the DVB-T taps from the drxk_filters.h are used.
3542*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003543static int SetDVBTStandard(struct drxk_state *state,
3544 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003545{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003546 u16 cmdResult = 0;
3547 u16 data = 0;
3548 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003549
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003550 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003551
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003552 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003553 /* added antenna switch */
3554 SwitchAntennaToDVBT(state);
3555 /* send OFDM reset command */
3556 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 -03003557 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003558 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003559
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003560 /* send OFDM setenv command */
3561 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3562 if (status < 0)
3563 goto error;
3564
3565 /* reset datapath for OFDM, processors first */
3566 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3567 if (status < 0)
3568 goto error;
3569 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3570 if (status < 0)
3571 goto error;
3572 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3573 if (status < 0)
3574 goto error;
3575
3576 /* IQM setup */
3577 /* synchronize on ofdstate->m_festart */
3578 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3579 if (status < 0)
3580 goto error;
3581 /* window size for clipping ADC detection */
3582 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3583 if (status < 0)
3584 goto error;
3585 /* window size for for sense pre-SAW detection */
3586 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3587 if (status < 0)
3588 goto error;
3589 /* sense threshold for sense pre-SAW detection */
3590 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3591 if (status < 0)
3592 goto error;
3593 status = SetIqmAf(state, true);
3594 if (status < 0)
3595 goto error;
3596
3597 status = write16(state, IQM_AF_AGC_RF__A, 0);
3598 if (status < 0)
3599 goto error;
3600
3601 /* Impulse noise cruncher setup */
3602 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3603 if (status < 0)
3604 goto error;
3605 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3606 if (status < 0)
3607 goto error;
3608 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3609 if (status < 0)
3610 goto error;
3611
3612 status = write16(state, IQM_RC_STRETCH__A, 16);
3613 if (status < 0)
3614 goto error;
3615 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3616 if (status < 0)
3617 goto error;
3618 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3619 if (status < 0)
3620 goto error;
3621 status = write16(state, IQM_CF_SCALE__A, 1600);
3622 if (status < 0)
3623 goto error;
3624 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3625 if (status < 0)
3626 goto error;
3627
3628 /* virtual clipping threshold for clipping ADC detection */
3629 status = write16(state, IQM_AF_CLP_TH__A, 448);
3630 if (status < 0)
3631 goto error;
3632 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3633 if (status < 0)
3634 goto error;
3635
3636 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3637 if (status < 0)
3638 goto error;
3639
3640 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3641 if (status < 0)
3642 goto error;
3643 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3644 if (status < 0)
3645 goto error;
3646 /* enable power measurement interrupt */
3647 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3648 if (status < 0)
3649 goto error;
3650 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3651 if (status < 0)
3652 goto error;
3653
3654 /* IQM will not be reset from here, sync ADC and update/init AGC */
3655 status = ADCSynchronization(state);
3656 if (status < 0)
3657 goto error;
3658 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3659 if (status < 0)
3660 goto error;
3661
3662 /* Halt SCU to enable safe non-atomic accesses */
3663 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3664 if (status < 0)
3665 goto error;
3666
3667 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3668 if (status < 0)
3669 goto error;
3670 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3671 if (status < 0)
3672 goto error;
3673
3674 /* Set Noise Estimation notch width and enable DC fix */
3675 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3676 if (status < 0)
3677 goto error;
3678 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3679 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3680 if (status < 0)
3681 goto error;
3682
3683 /* Activate SCU to enable SCU commands */
3684 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3685 if (status < 0)
3686 goto error;
3687
3688 if (!state->m_DRXK_A3_ROM_CODE) {
3689 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3690 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3691 if (status < 0)
3692 goto error;
3693 }
3694
3695 /* OFDM_SC setup */
3696#ifdef COMPILE_FOR_NONRT
3697 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3698 if (status < 0)
3699 goto error;
3700 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3701 if (status < 0)
3702 goto error;
3703#endif
3704
3705 /* FEC setup */
3706 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3707 if (status < 0)
3708 goto error;
3709
3710
3711#ifdef COMPILE_FOR_NONRT
3712 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3713 if (status < 0)
3714 goto error;
3715#else
3716 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3717 if (status < 0)
3718 goto error;
3719#endif
3720 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3721 if (status < 0)
3722 goto error;
3723
3724 /* Setup MPEG bus */
3725 status = MPEGTSDtoSetup(state, OM_DVBT);
3726 if (status < 0)
3727 goto error;
3728 /* Set DVBT Presets */
3729 status = DVBTActivatePresets(state);
3730 if (status < 0)
3731 goto error;
3732
3733error:
3734 if (status < 0)
3735 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003736 return status;
3737}
3738
3739/*============================================================================*/
3740/**
3741* \brief Start dvbt demodulating for channel.
3742* \param demod instance of demodulator.
3743* \return DRXStatus_t.
3744*/
3745static int DVBTStart(struct drxk_state *state)
3746{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003747 u16 param1;
3748 int status;
3749 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003750
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003751 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003752 /* Start correct processes to get in lock */
3753 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003754 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3755 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3756 if (status < 0)
3757 goto error;
3758 /* Start FEC OC */
3759 status = MPEGTSStart(state);
3760 if (status < 0)
3761 goto error;
3762 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3763 if (status < 0)
3764 goto error;
3765error:
3766 if (status < 0)
3767 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003768 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003769}
3770
3771
3772/*============================================================================*/
3773
3774/**
3775* \brief Set up dvbt demodulator for channel.
3776* \param demod instance of demodulator.
3777* \return DRXStatus_t.
3778* // original DVBTSetChannel()
3779*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003780static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3781 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003782{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003783 u16 cmdResult = 0;
3784 u16 transmissionParams = 0;
3785 u16 operationMode = 0;
3786 u32 iqmRcRateOfs = 0;
3787 u32 bandwidth = 0;
3788 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003789 int status;
3790
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003791 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003792
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003793 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3794 if (status < 0)
3795 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003796
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003797 /* Halt SCU to enable safe non-atomic accesses */
3798 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3799 if (status < 0)
3800 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003801
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003802 /* Stop processors */
3803 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3804 if (status < 0)
3805 goto error;
3806 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3807 if (status < 0)
3808 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003809
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003810 /* Mandatory fix, always stop CP, required to set spl offset back to
3811 hardware default (is set to 0 by ucode during pilot detection */
3812 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3813 if (status < 0)
3814 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003815
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003816 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003817
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003818 /* mode */
3819 switch (state->param.u.ofdm.transmission_mode) {
3820 case TRANSMISSION_MODE_AUTO:
3821 default:
3822 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3823 /* fall through , try first guess DRX_FFTMODE_8K */
3824 case TRANSMISSION_MODE_8K:
3825 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003826 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003827 case TRANSMISSION_MODE_2K:
3828 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003829 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003830 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003831
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003832 /* guard */
3833 switch (state->param.u.ofdm.guard_interval) {
3834 default:
3835 case GUARD_INTERVAL_AUTO:
3836 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3837 /* fall through , try first guess DRX_GUARD_1DIV4 */
3838 case GUARD_INTERVAL_1_4:
3839 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003840 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003841 case GUARD_INTERVAL_1_32:
3842 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003843 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003844 case GUARD_INTERVAL_1_16:
3845 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003846 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003847 case GUARD_INTERVAL_1_8:
3848 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003849 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003850 }
3851
3852 /* hierarchy */
3853 switch (state->param.u.ofdm.hierarchy_information) {
3854 case HIERARCHY_AUTO:
3855 case HIERARCHY_NONE:
3856 default:
3857 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3858 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3859 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3860 /* break; */
3861 case HIERARCHY_1:
3862 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3863 break;
3864 case HIERARCHY_2:
3865 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3866 break;
3867 case HIERARCHY_4:
3868 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3869 break;
3870 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003871
3872
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003873 /* constellation */
3874 switch (state->param.u.ofdm.constellation) {
3875 case QAM_AUTO:
3876 default:
3877 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3878 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3879 case QAM_64:
3880 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3881 break;
3882 case QPSK:
3883 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3884 break;
3885 case QAM_16:
3886 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3887 break;
3888 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003889#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003890 /* No hierachical channels support in BDA */
3891 /* Priority (only for hierarchical channels) */
3892 switch (channel->priority) {
3893 case DRX_PRIORITY_LOW:
3894 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3895 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3896 OFDM_EC_SB_PRIOR_LO);
3897 break;
3898 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003899 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003900 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3901 OFDM_EC_SB_PRIOR_HI));
3902 break;
3903 case DRX_PRIORITY_UNKNOWN: /* fall through */
3904 default:
3905 status = -EINVAL;
3906 goto error;
3907 }
3908#else
3909 /* Set Priorty high */
3910 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3911 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3912 if (status < 0)
3913 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003914#endif
3915
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003916 /* coderate */
3917 switch (state->param.u.ofdm.code_rate_HP) {
3918 case FEC_AUTO:
3919 default:
3920 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3921 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3922 case FEC_2_3:
3923 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3924 break;
3925 case FEC_1_2:
3926 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3927 break;
3928 case FEC_3_4:
3929 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3930 break;
3931 case FEC_5_6:
3932 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3933 break;
3934 case FEC_7_8:
3935 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3936 break;
3937 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003938
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003939 /* SAW filter selection: normaly not necesarry, but if wanted
3940 the application can select a SAW filter via the driver by using UIOs */
3941 /* First determine real bandwidth (Hz) */
3942 /* Also set delay for impulse noise cruncher */
3943 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3944 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3945 functions */
3946 switch (state->param.u.ofdm.bandwidth) {
3947 case BANDWIDTH_AUTO:
3948 case BANDWIDTH_8_MHZ:
3949 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3950 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003951 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003952 goto error;
3953 /* cochannel protection for PAL 8 MHz */
3954 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3955 if (status < 0)
3956 goto error;
3957 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3958 if (status < 0)
3959 goto error;
3960 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3961 if (status < 0)
3962 goto error;
3963 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3964 if (status < 0)
3965 goto error;
3966 break;
3967 case BANDWIDTH_7_MHZ:
3968 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3969 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3970 if (status < 0)
3971 goto error;
3972 /* cochannel protection for PAL 7 MHz */
3973 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3974 if (status < 0)
3975 goto error;
3976 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3977 if (status < 0)
3978 goto error;
3979 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3980 if (status < 0)
3981 goto error;
3982 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3983 if (status < 0)
3984 goto error;
3985 break;
3986 case BANDWIDTH_6_MHZ:
3987 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3988 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3989 if (status < 0)
3990 goto error;
3991 /* cochannel protection for NTSC 6 MHz */
3992 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3993 if (status < 0)
3994 goto error;
3995 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3996 if (status < 0)
3997 goto error;
3998 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3999 if (status < 0)
4000 goto error;
4001 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
4002 if (status < 0)
4003 goto error;
4004 break;
4005 default:
4006 status = -EINVAL;
4007 goto error;
4008 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004009
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004010 if (iqmRcRateOfs == 0) {
4011 /* Now compute IQM_RC_RATE_OFS
4012 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4013 =>
4014 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4015 */
4016 /* (SysFreq / BandWidth) * (2^28) */
4017 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4018 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4019 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4020 iqmRcRateOfs = Frac28a((u32)
4021 ((state->m_sysClockFreq *
4022 1000) / 3), bandwidth);
4023 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4024 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4025 iqmRcRateOfs += 0x80L;
4026 iqmRcRateOfs = iqmRcRateOfs >> 7;
4027 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4028 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4029 }
4030
4031 iqmRcRateOfs &=
4032 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4033 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4034 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4035 if (status < 0)
4036 goto error;
4037
4038 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004039
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004040#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004041 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4042 if (status < 0)
4043 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004044#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004045 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4046 if (status < 0)
4047 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004048
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004049 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004050
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004051 /* Activate SCU to enable SCU commands */
4052 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4053 if (status < 0)
4054 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004055
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004056 /* Enable SC after setting all other parameters */
4057 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4058 if (status < 0)
4059 goto error;
4060 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4061 if (status < 0)
4062 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004063
4064
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004065 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4066 if (status < 0)
4067 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004068
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004069 /* Write SC parameter registers, set all AUTO flags in operation mode */
4070 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4071 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4072 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4073 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4074 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4075 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4076 0, transmissionParams, param1, 0, 0, 0);
4077 if (status < 0)
4078 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004079
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004080 if (!state->m_DRXK_A3_ROM_CODE)
4081 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4082error:
4083 if (status < 0)
4084 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004085
4086 return status;
4087}
4088
4089
4090/*============================================================================*/
4091
4092/**
4093* \brief Retreive lock status .
4094* \param demod Pointer to demodulator instance.
4095* \param lockStat Pointer to lock status structure.
4096* \return DRXStatus_t.
4097*
4098*/
4099static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4100{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004101 int status;
4102 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4103 OFDM_SC_RA_RAM_LOCK_FEC__M);
4104 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4105 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004106
Oliver Endrissebc7de22011-07-03 13:49:44 -03004107 u16 ScRaRamLock = 0;
4108 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004109
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004110 dprintk(1, "\n");
4111
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004112 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004113 /* driver 0.9.0 */
4114 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004115 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004116 if (status < 0)
4117 goto end;
4118 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4119 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004120
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004121 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004122 if (status < 0)
4123 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004124
Oliver Endrissebc7de22011-07-03 13:49:44 -03004125 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4126 *pLockStatus = MPEG_LOCK;
4127 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4128 *pLockStatus = FEC_LOCK;
4129 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4130 *pLockStatus = DEMOD_LOCK;
4131 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4132 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004133end:
4134 if (status < 0)
4135 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004136
Oliver Endrissebc7de22011-07-03 13:49:44 -03004137 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004138}
4139
Oliver Endrissebc7de22011-07-03 13:49:44 -03004140static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004141{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004142 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004143 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004144
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004145 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004146 status = CtrlPowerMode(state, &powerMode);
4147 if (status < 0)
4148 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004149
Oliver Endrissebc7de22011-07-03 13:49:44 -03004150 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004151}
4152
4153
Oliver Endrissebc7de22011-07-03 13:49:44 -03004154/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004155static int PowerDownQAM(struct drxk_state *state)
4156{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004157 u16 data = 0;
4158 u16 cmdResult;
4159 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004160
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004161 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004162 status = read16(state, SCU_COMM_EXEC__A, &data);
4163 if (status < 0)
4164 goto error;
4165 if (data == SCU_COMM_EXEC_ACTIVE) {
4166 /*
4167 STOP demodulator
4168 QAM and HW blocks
4169 */
4170 /* stop all comstate->m_exec */
4171 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004172 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004173 goto error;
4174 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 -03004175 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004176 goto error;
4177 }
4178 /* powerdown AFE */
4179 status = SetIqmAf(state, false);
4180
4181error:
4182 if (status < 0)
4183 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004184
Oliver Endrissebc7de22011-07-03 13:49:44 -03004185 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004186}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004187
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004188/*============================================================================*/
4189
4190/**
4191* \brief Setup of the QAM Measurement intervals for signal quality
4192* \param demod instance of demod.
4193* \param constellation current constellation.
4194* \return DRXStatus_t.
4195*
4196* NOTE:
4197* Take into account that for certain settings the errorcounters can overflow.
4198* The implementation does not check this.
4199*
4200*/
4201static int SetQAMMeasurement(struct drxk_state *state,
4202 enum EDrxkConstellation constellation,
4203 u32 symbolRate)
4204{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004205 u32 fecBitsDesired = 0; /* BER accounting period */
4206 u32 fecRsPeriodTotal = 0; /* Total period */
4207 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4208 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004209 int status = 0;
4210
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004211 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004212
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004213 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004214 /* fecBitsDesired = symbolRate [kHz] *
4215 FrameLenght [ms] *
4216 (constellation + 1) *
4217 SyncLoss (== 1) *
4218 ViterbiLoss (==1)
4219 */
4220 switch (constellation) {
4221 case DRX_CONSTELLATION_QAM16:
4222 fecBitsDesired = 4 * symbolRate;
4223 break;
4224 case DRX_CONSTELLATION_QAM32:
4225 fecBitsDesired = 5 * symbolRate;
4226 break;
4227 case DRX_CONSTELLATION_QAM64:
4228 fecBitsDesired = 6 * symbolRate;
4229 break;
4230 case DRX_CONSTELLATION_QAM128:
4231 fecBitsDesired = 7 * symbolRate;
4232 break;
4233 case DRX_CONSTELLATION_QAM256:
4234 fecBitsDesired = 8 * symbolRate;
4235 break;
4236 default:
4237 status = -EINVAL;
4238 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004239 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004240 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004241
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004242 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4243 fecBitsDesired *= 500; /* meas. period [ms] */
4244
4245 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4246 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4247 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4248
4249 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4250 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4251 if (fecRsPrescale == 0) {
4252 /* Divide by zero (though impossible) */
4253 status = -EINVAL;
4254 if (status < 0)
4255 goto error;
4256 }
4257 fecRsPeriod =
4258 ((u16) fecRsPeriodTotal +
4259 (fecRsPrescale >> 1)) / fecRsPrescale;
4260
4261 /* write corresponding registers */
4262 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4263 if (status < 0)
4264 goto error;
4265 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4266 if (status < 0)
4267 goto error;
4268 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4269error:
4270 if (status < 0)
4271 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004272 return status;
4273}
4274
Oliver Endrissebc7de22011-07-03 13:49:44 -03004275static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004276{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004277 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004278
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004279 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004280 /* QAM Equalizer Setup */
4281 /* Equalizer */
4282 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4283 if (status < 0)
4284 goto error;
4285 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4286 if (status < 0)
4287 goto error;
4288 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4289 if (status < 0)
4290 goto error;
4291 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4292 if (status < 0)
4293 goto error;
4294 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4295 if (status < 0)
4296 goto error;
4297 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4298 if (status < 0)
4299 goto error;
4300 /* Decision Feedback Equalizer */
4301 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4302 if (status < 0)
4303 goto error;
4304 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4305 if (status < 0)
4306 goto error;
4307 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4308 if (status < 0)
4309 goto error;
4310 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4311 if (status < 0)
4312 goto error;
4313 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4314 if (status < 0)
4315 goto error;
4316 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4317 if (status < 0)
4318 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004319
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004320 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4321 if (status < 0)
4322 goto error;
4323 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4324 if (status < 0)
4325 goto error;
4326 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4327 if (status < 0)
4328 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004329
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004330 /* QAM Slicer Settings */
4331 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4332 if (status < 0)
4333 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004334
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004335 /* QAM Loop Controller Coeficients */
4336 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4337 if (status < 0)
4338 goto error;
4339 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4340 if (status < 0)
4341 goto error;
4342 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4343 if (status < 0)
4344 goto error;
4345 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4346 if (status < 0)
4347 goto error;
4348 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4349 if (status < 0)
4350 goto error;
4351 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4352 if (status < 0)
4353 goto error;
4354 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4355 if (status < 0)
4356 goto error;
4357 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4358 if (status < 0)
4359 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004360
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004361 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4362 if (status < 0)
4363 goto error;
4364 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4365 if (status < 0)
4366 goto error;
4367 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4368 if (status < 0)
4369 goto error;
4370 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4371 if (status < 0)
4372 goto error;
4373 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4374 if (status < 0)
4375 goto error;
4376 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4377 if (status < 0)
4378 goto error;
4379 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4380 if (status < 0)
4381 goto error;
4382 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4383 if (status < 0)
4384 goto error;
4385 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4386 if (status < 0)
4387 goto error;
4388 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4389 if (status < 0)
4390 goto error;
4391 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4392 if (status < 0)
4393 goto error;
4394 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4395 if (status < 0)
4396 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004397
4398
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004399 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004400
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004401 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4402 if (status < 0)
4403 goto error;
4404 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4405 if (status < 0)
4406 goto error;
4407 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4408 if (status < 0)
4409 goto error;
4410 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4411 if (status < 0)
4412 goto error;
4413 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4414 if (status < 0)
4415 goto error;
4416 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4417 if (status < 0)
4418 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004419
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004420 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4421 if (status < 0)
4422 goto error;
4423 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4424 if (status < 0)
4425 goto error;
4426 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4427 if (status < 0)
4428 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004429
4430
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004431 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004432
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004433 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4434 if (status < 0)
4435 goto error;
4436 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4437 if (status < 0)
4438 goto error;
4439 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4440 if (status < 0)
4441 goto error;
4442 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4443 if (status < 0)
4444 goto error;
4445 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4446 if (status < 0)
4447 goto error;
4448 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4449 if (status < 0)
4450 goto error;
4451 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4452 if (status < 0)
4453 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004454
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004455error:
4456 if (status < 0)
4457 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004458 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004459}
4460
4461/*============================================================================*/
4462
4463/**
4464* \brief QAM32 specific setup
4465* \param demod instance of demod.
4466* \return DRXStatus_t.
4467*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004468static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004469{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004470 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004471
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004472 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004473
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004474 /* QAM Equalizer Setup */
4475 /* Equalizer */
4476 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4477 if (status < 0)
4478 goto error;
4479 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4480 if (status < 0)
4481 goto error;
4482 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4483 if (status < 0)
4484 goto error;
4485 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4486 if (status < 0)
4487 goto error;
4488 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4489 if (status < 0)
4490 goto error;
4491 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4492 if (status < 0)
4493 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004494
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004495 /* Decision Feedback Equalizer */
4496 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4497 if (status < 0)
4498 goto error;
4499 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4500 if (status < 0)
4501 goto error;
4502 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4503 if (status < 0)
4504 goto error;
4505 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4506 if (status < 0)
4507 goto error;
4508 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4509 if (status < 0)
4510 goto error;
4511 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4512 if (status < 0)
4513 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004514
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004515 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4516 if (status < 0)
4517 goto error;
4518 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4519 if (status < 0)
4520 goto error;
4521 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4522 if (status < 0)
4523 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004524
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004525 /* QAM Slicer Settings */
4526
4527 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4528 if (status < 0)
4529 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004530
4531
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004532 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004533
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004534 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4535 if (status < 0)
4536 goto error;
4537 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4538 if (status < 0)
4539 goto error;
4540 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4541 if (status < 0)
4542 goto error;
4543 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4544 if (status < 0)
4545 goto error;
4546 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4547 if (status < 0)
4548 goto error;
4549 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4550 if (status < 0)
4551 goto error;
4552 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4553 if (status < 0)
4554 goto error;
4555 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4556 if (status < 0)
4557 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004558
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004559 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4560 if (status < 0)
4561 goto error;
4562 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4563 if (status < 0)
4564 goto error;
4565 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4566 if (status < 0)
4567 goto error;
4568 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4569 if (status < 0)
4570 goto error;
4571 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4572 if (status < 0)
4573 goto error;
4574 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4575 if (status < 0)
4576 goto error;
4577 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4578 if (status < 0)
4579 goto error;
4580 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4581 if (status < 0)
4582 goto error;
4583 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4584 if (status < 0)
4585 goto error;
4586 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4587 if (status < 0)
4588 goto error;
4589 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4590 if (status < 0)
4591 goto error;
4592 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4593 if (status < 0)
4594 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004595
4596
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004597 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004598
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004599 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4600 if (status < 0)
4601 goto error;
4602 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4603 if (status < 0)
4604 goto error;
4605 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4606 if (status < 0)
4607 goto error;
4608 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4609 if (status < 0)
4610 goto error;
4611 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4612 if (status < 0)
4613 goto error;
4614 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4615 if (status < 0)
4616 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004617
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004618 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4619 if (status < 0)
4620 goto error;
4621 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4622 if (status < 0)
4623 goto error;
4624 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4625 if (status < 0)
4626 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004627
4628
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004629 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004630
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004631 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4632 if (status < 0)
4633 goto error;
4634 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4635 if (status < 0)
4636 goto error;
4637 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4638 if (status < 0)
4639 goto error;
4640 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4641 if (status < 0)
4642 goto error;
4643 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4644 if (status < 0)
4645 goto error;
4646 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4647 if (status < 0)
4648 goto error;
4649 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4650error:
4651 if (status < 0)
4652 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004653 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004654}
4655
4656/*============================================================================*/
4657
4658/**
4659* \brief QAM64 specific setup
4660* \param demod instance of demod.
4661* \return DRXStatus_t.
4662*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004663static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004664{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004665 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004666
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004667 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004668 /* QAM Equalizer Setup */
4669 /* Equalizer */
4670 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4671 if (status < 0)
4672 goto error;
4673 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4674 if (status < 0)
4675 goto error;
4676 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4677 if (status < 0)
4678 goto error;
4679 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4680 if (status < 0)
4681 goto error;
4682 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4683 if (status < 0)
4684 goto error;
4685 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4686 if (status < 0)
4687 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004688
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004689 /* Decision Feedback Equalizer */
4690 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4691 if (status < 0)
4692 goto error;
4693 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4694 if (status < 0)
4695 goto error;
4696 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4697 if (status < 0)
4698 goto error;
4699 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4700 if (status < 0)
4701 goto error;
4702 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4703 if (status < 0)
4704 goto error;
4705 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4706 if (status < 0)
4707 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004708
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004709 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4710 if (status < 0)
4711 goto error;
4712 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4713 if (status < 0)
4714 goto error;
4715 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4716 if (status < 0)
4717 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004718
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004719 /* QAM Slicer Settings */
4720 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4721 if (status < 0)
4722 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004723
4724
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004725 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004726
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004727 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4728 if (status < 0)
4729 goto error;
4730 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4731 if (status < 0)
4732 goto error;
4733 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4734 if (status < 0)
4735 goto error;
4736 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4737 if (status < 0)
4738 goto error;
4739 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4740 if (status < 0)
4741 goto error;
4742 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4743 if (status < 0)
4744 goto error;
4745 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4746 if (status < 0)
4747 goto error;
4748 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4749 if (status < 0)
4750 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004751
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004752 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4753 if (status < 0)
4754 goto error;
4755 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4756 if (status < 0)
4757 goto error;
4758 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4759 if (status < 0)
4760 goto error;
4761 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4762 if (status < 0)
4763 goto error;
4764 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4765 if (status < 0)
4766 goto error;
4767 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4768 if (status < 0)
4769 goto error;
4770 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4771 if (status < 0)
4772 goto error;
4773 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4774 if (status < 0)
4775 goto error;
4776 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4777 if (status < 0)
4778 goto error;
4779 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4780 if (status < 0)
4781 goto error;
4782 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4783 if (status < 0)
4784 goto error;
4785 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4786 if (status < 0)
4787 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004788
4789
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004790 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004791
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004792 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4793 if (status < 0)
4794 goto error;
4795 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4796 if (status < 0)
4797 goto error;
4798 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4799 if (status < 0)
4800 goto error;
4801 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4802 if (status < 0)
4803 goto error;
4804 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4805 if (status < 0)
4806 goto error;
4807 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4808 if (status < 0)
4809 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004810
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004811 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4812 if (status < 0)
4813 goto error;
4814 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4815 if (status < 0)
4816 goto error;
4817 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4818 if (status < 0)
4819 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004820
4821
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004822 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004823
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004824 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4825 if (status < 0)
4826 goto error;
4827 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4828 if (status < 0)
4829 goto error;
4830 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4831 if (status < 0)
4832 goto error;
4833 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4834 if (status < 0)
4835 goto error;
4836 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4837 if (status < 0)
4838 goto error;
4839 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4840 if (status < 0)
4841 goto error;
4842 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4843error:
4844 if (status < 0)
4845 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004846
Oliver Endrissebc7de22011-07-03 13:49:44 -03004847 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004848}
4849
4850/*============================================================================*/
4851
4852/**
4853* \brief QAM128 specific setup
4854* \param demod: instance of demod.
4855* \return DRXStatus_t.
4856*/
4857static int SetQAM128(struct drxk_state *state)
4858{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004859 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004860
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004861 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004862 /* QAM Equalizer Setup */
4863 /* Equalizer */
4864 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4865 if (status < 0)
4866 goto error;
4867 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4868 if (status < 0)
4869 goto error;
4870 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4871 if (status < 0)
4872 goto error;
4873 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4874 if (status < 0)
4875 goto error;
4876 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4877 if (status < 0)
4878 goto error;
4879 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4880 if (status < 0)
4881 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004882
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004883 /* Decision Feedback Equalizer */
4884 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4885 if (status < 0)
4886 goto error;
4887 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4888 if (status < 0)
4889 goto error;
4890 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4891 if (status < 0)
4892 goto error;
4893 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4894 if (status < 0)
4895 goto error;
4896 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4897 if (status < 0)
4898 goto error;
4899 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4900 if (status < 0)
4901 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004902
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004903 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4904 if (status < 0)
4905 goto error;
4906 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4907 if (status < 0)
4908 goto error;
4909 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4910 if (status < 0)
4911 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004912
4913
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004914 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004915
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004916 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4917 if (status < 0)
4918 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004919
4920
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004921 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004922
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004923 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4924 if (status < 0)
4925 goto error;
4926 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4927 if (status < 0)
4928 goto error;
4929 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4930 if (status < 0)
4931 goto error;
4932 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4933 if (status < 0)
4934 goto error;
4935 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4936 if (status < 0)
4937 goto error;
4938 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4939 if (status < 0)
4940 goto error;
4941 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4942 if (status < 0)
4943 goto error;
4944 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4945 if (status < 0)
4946 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004947
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004948 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4949 if (status < 0)
4950 goto error;
4951 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4952 if (status < 0)
4953 goto error;
4954 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4955 if (status < 0)
4956 goto error;
4957 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4958 if (status < 0)
4959 goto error;
4960 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4961 if (status < 0)
4962 goto error;
4963 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4964 if (status < 0)
4965 goto error;
4966 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4967 if (status < 0)
4968 goto error;
4969 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4970 if (status < 0)
4971 goto error;
4972 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4973 if (status < 0)
4974 goto error;
4975 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4976 if (status < 0)
4977 goto error;
4978 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4979 if (status < 0)
4980 goto error;
4981 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4982 if (status < 0)
4983 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004984
4985
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004986 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004987
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004988 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4989 if (status < 0)
4990 goto error;
4991 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4992 if (status < 0)
4993 goto error;
4994 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4995 if (status < 0)
4996 goto error;
4997 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4998 if (status < 0)
4999 goto error;
5000 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
5001 if (status < 0)
5002 goto error;
5003 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5004 if (status < 0)
5005 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005006
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005007 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5008 if (status < 0)
5009 goto error;
5010 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5011 if (status < 0)
5012 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005013
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005014 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5015 if (status < 0)
5016 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005017
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005018 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005019
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005020 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5021 if (status < 0)
5022 goto error;
5023 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5024 if (status < 0)
5025 goto error;
5026 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5027 if (status < 0)
5028 goto error;
5029 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5030 if (status < 0)
5031 goto error;
5032 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5033 if (status < 0)
5034 goto error;
5035 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5036 if (status < 0)
5037 goto error;
5038 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5039error:
5040 if (status < 0)
5041 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005042
Oliver Endrissebc7de22011-07-03 13:49:44 -03005043 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005044}
5045
5046/*============================================================================*/
5047
5048/**
5049* \brief QAM256 specific setup
5050* \param demod: instance of demod.
5051* \return DRXStatus_t.
5052*/
5053static int SetQAM256(struct drxk_state *state)
5054{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005055 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005056
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005057 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005058 /* QAM Equalizer Setup */
5059 /* Equalizer */
5060 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5061 if (status < 0)
5062 goto error;
5063 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5064 if (status < 0)
5065 goto error;
5066 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5067 if (status < 0)
5068 goto error;
5069 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5070 if (status < 0)
5071 goto error;
5072 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5073 if (status < 0)
5074 goto error;
5075 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5076 if (status < 0)
5077 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005078
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005079 /* Decision Feedback Equalizer */
5080 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5081 if (status < 0)
5082 goto error;
5083 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5084 if (status < 0)
5085 goto error;
5086 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5087 if (status < 0)
5088 goto error;
5089 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5090 if (status < 0)
5091 goto error;
5092 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5093 if (status < 0)
5094 goto error;
5095 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5096 if (status < 0)
5097 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005098
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005099 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5100 if (status < 0)
5101 goto error;
5102 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5103 if (status < 0)
5104 goto error;
5105 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5106 if (status < 0)
5107 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005108
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005109 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005110
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005111 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5112 if (status < 0)
5113 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005114
5115
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005116 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005117
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005118 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5119 if (status < 0)
5120 goto error;
5121 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5122 if (status < 0)
5123 goto error;
5124 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5125 if (status < 0)
5126 goto error;
5127 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5128 if (status < 0)
5129 goto error;
5130 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5131 if (status < 0)
5132 goto error;
5133 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5134 if (status < 0)
5135 goto error;
5136 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5137 if (status < 0)
5138 goto error;
5139 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5140 if (status < 0)
5141 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005142
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005143 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5144 if (status < 0)
5145 goto error;
5146 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5147 if (status < 0)
5148 goto error;
5149 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5150 if (status < 0)
5151 goto error;
5152 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5153 if (status < 0)
5154 goto error;
5155 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5156 if (status < 0)
5157 goto error;
5158 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5159 if (status < 0)
5160 goto error;
5161 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5162 if (status < 0)
5163 goto error;
5164 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5165 if (status < 0)
5166 goto error;
5167 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5168 if (status < 0)
5169 goto error;
5170 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5171 if (status < 0)
5172 goto error;
5173 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5174 if (status < 0)
5175 goto error;
5176 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5177 if (status < 0)
5178 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005179
5180
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005181 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005182
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005183 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5184 if (status < 0)
5185 goto error;
5186 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5187 if (status < 0)
5188 goto error;
5189 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5190 if (status < 0)
5191 goto error;
5192 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5193 if (status < 0)
5194 goto error;
5195 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5196 if (status < 0)
5197 goto error;
5198 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5199 if (status < 0)
5200 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005201
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005202 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5203 if (status < 0)
5204 goto error;
5205 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5206 if (status < 0)
5207 goto error;
5208 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5209 if (status < 0)
5210 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005211
5212
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005213 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005214
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005215 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5216 if (status < 0)
5217 goto error;
5218 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5219 if (status < 0)
5220 goto error;
5221 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5222 if (status < 0)
5223 goto error;
5224 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5225 if (status < 0)
5226 goto error;
5227 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5228 if (status < 0)
5229 goto error;
5230 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5231 if (status < 0)
5232 goto error;
5233 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5234error:
5235 if (status < 0)
5236 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005237 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005238}
5239
5240
5241/*============================================================================*/
5242/**
5243* \brief Reset QAM block.
5244* \param demod: instance of demod.
5245* \param channel: pointer to channel data.
5246* \return DRXStatus_t.
5247*/
5248static int QAMResetQAM(struct drxk_state *state)
5249{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005250 int status;
5251 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005252
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005253 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005254 /* Stop QAM comstate->m_exec */
5255 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5256 if (status < 0)
5257 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005258
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005259 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5260error:
5261 if (status < 0)
5262 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005263 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005264}
5265
5266/*============================================================================*/
5267
5268/**
5269* \brief Set QAM symbolrate.
5270* \param demod: instance of demod.
5271* \param channel: pointer to channel data.
5272* \return DRXStatus_t.
5273*/
5274static int QAMSetSymbolrate(struct drxk_state *state)
5275{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005276 u32 adcFrequency = 0;
5277 u32 symbFreq = 0;
5278 u32 iqmRcRate = 0;
5279 u16 ratesel = 0;
5280 u32 lcSymbRate = 0;
5281 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005282
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005283 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005284 /* Select & calculate correct IQM rate */
5285 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5286 ratesel = 0;
5287 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
5288 if (state->param.u.qam.symbol_rate <= 1188750)
5289 ratesel = 3;
5290 else if (state->param.u.qam.symbol_rate <= 2377500)
5291 ratesel = 2;
5292 else if (state->param.u.qam.symbol_rate <= 4755000)
5293 ratesel = 1;
5294 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5295 if (status < 0)
5296 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005297
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005298 /*
5299 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5300 */
5301 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5302 if (symbFreq == 0) {
5303 /* Divide by zero */
5304 status = -EINVAL;
5305 goto error;
5306 }
5307 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5308 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5309 (1 << 23);
5310 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5311 if (status < 0)
5312 goto error;
5313 state->m_iqmRcRate = iqmRcRate;
5314 /*
5315 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5316 */
5317 symbFreq = state->param.u.qam.symbol_rate;
5318 if (adcFrequency == 0) {
5319 /* Divide by zero */
5320 status = -EINVAL;
5321 goto error;
5322 }
5323 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5324 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5325 16);
5326 if (lcSymbRate > 511)
5327 lcSymbRate = 511;
5328 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005329
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005330error:
5331 if (status < 0)
5332 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005333 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005334}
5335
5336/*============================================================================*/
5337
5338/**
5339* \brief Get QAM lock status.
5340* \param demod: instance of demod.
5341* \param channel: pointer to channel data.
5342* \return DRXStatus_t.
5343*/
5344
5345static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5346{
5347 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005348 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005349
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005350 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005351 *pLockStatus = NOT_LOCKED;
5352 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005353 SCU_RAM_COMMAND_STANDARD_QAM |
5354 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5355 Result);
5356 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005357 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005358
5359 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005360 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005361 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005362 /* 0x4000 DEMOD LOCKED */
5363 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005364 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005365 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5366 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005367 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005368 /* 0xC000 NEVER LOCKED */
5369 /* (system will never be able to lock to the signal) */
5370 /* TODO: check this, intermediate & standard specific lock states are not
5371 taken into account here */
5372 *pLockStatus = NEVER_LOCK;
5373 }
5374 return status;
5375}
5376
5377#define QAM_MIRROR__M 0x03
5378#define QAM_MIRROR_NORMAL 0x00
5379#define QAM_MIRRORED 0x01
5380#define QAM_MIRROR_AUTO_ON 0x02
5381#define QAM_LOCKRANGE__M 0x10
5382#define QAM_LOCKRANGE_NORMAL 0x10
5383
Oliver Endrissebc7de22011-07-03 13:49:44 -03005384static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5385 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005386{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005387 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005388 u8 parameterLen;
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005389 u16 setEnvParameters[5] = { 0, 0, 0, 0, 0 };
Oliver Endrissebc7de22011-07-03 13:49:44 -03005390 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5391 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005392
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005393 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005394 /*
5395 STEP 1: reset demodulator
5396 resets FEC DI and FEC RS
5397 resets QAM block
5398 resets SCU variables
5399 */
5400 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005401 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005402 goto error;
5403 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5404 if (status < 0)
5405 goto error;
5406 status = QAMResetQAM(state);
5407 if (status < 0)
5408 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005409
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005410 /*
5411 STEP 2: configure demodulator
5412 -set env
5413 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5414 */
5415 status = QAMSetSymbolrate(state);
5416 if (status < 0)
5417 goto error;
5418
5419 /* Env parameters */
5420 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
5421 if (state->m_OperationMode == OM_QAM_ITU_C)
5422 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
5423 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5424 /* check for LOCKRANGE Extented */
5425 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5426 parameterLen = 4;
5427
5428 /* Set params */
5429 switch (state->param.u.qam.modulation) {
5430 case QAM_256:
5431 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5432 break;
5433 case QAM_AUTO:
5434 case QAM_64:
5435 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5436 break;
5437 case QAM_16:
5438 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5439 break;
5440 case QAM_32:
5441 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5442 break;
5443 case QAM_128:
5444 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5445 break;
5446 default:
5447 status = -EINVAL;
5448 break;
5449 }
5450 if (status < 0)
5451 goto error;
5452 setParamParameters[0] = state->m_Constellation; /* constellation */
5453 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5454
5455 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005456 if (status < 0) {
5457 /* Fall-back to the simpler call */
5458 setParamParameters[0] = QAM_TOP_ANNEX_A;
5459 if (state->m_OperationMode == OM_QAM_ITU_C)
5460 setEnvParameters[0] = QAM_TOP_ANNEX_C; /* Annex */
5461 else
5462 setEnvParameters[0] = 0;
5463
5464 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 -03005465 if (status < 0)
5466 goto error;
5467
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005468 setParamParameters[0] = state->m_Constellation; /* constellation */
5469 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5470
5471 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
5472 }
5473 if (status < 0)
5474 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005475
5476 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5477 setup constellation independent registers */
5478#if 0
5479 status = SetFrequency(channel, tunerFreqOffset));
5480 if (status < 0)
5481 goto error;
5482#endif
5483 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5484 if (status < 0)
5485 goto error;
5486
5487 /* Setup BER measurement */
5488 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5489 if (status < 0)
5490 goto error;
5491
5492 /* Reset default values */
5493 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5494 if (status < 0)
5495 goto error;
5496 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5497 if (status < 0)
5498 goto error;
5499
5500 /* Reset default LC values */
5501 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5502 if (status < 0)
5503 goto error;
5504 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5505 if (status < 0)
5506 goto error;
5507 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5508 if (status < 0)
5509 goto error;
5510 status = write16(state, QAM_LC_MODE__A, 7);
5511 if (status < 0)
5512 goto error;
5513
5514 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5515 if (status < 0)
5516 goto error;
5517 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5518 if (status < 0)
5519 goto error;
5520 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5521 if (status < 0)
5522 goto error;
5523 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5524 if (status < 0)
5525 goto error;
5526 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5527 if (status < 0)
5528 goto error;
5529 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5530 if (status < 0)
5531 goto error;
5532 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5533 if (status < 0)
5534 goto error;
5535 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5536 if (status < 0)
5537 goto error;
5538 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5539 if (status < 0)
5540 goto error;
5541 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5542 if (status < 0)
5543 goto error;
5544 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5545 if (status < 0)
5546 goto error;
5547 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5548 if (status < 0)
5549 goto error;
5550 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5551 if (status < 0)
5552 goto error;
5553 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5554 if (status < 0)
5555 goto error;
5556 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5557 if (status < 0)
5558 goto error;
5559
5560 /* Mirroring, QAM-block starting point not inverted */
5561 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5562 if (status < 0)
5563 goto error;
5564
5565 /* Halt SCU to enable safe non-atomic accesses */
5566 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5567 if (status < 0)
5568 goto error;
5569
5570 /* STEP 4: constellation specific setup */
5571 switch (state->param.u.qam.modulation) {
5572 case QAM_16:
5573 status = SetQAM16(state);
5574 break;
5575 case QAM_32:
5576 status = SetQAM32(state);
5577 break;
5578 case QAM_AUTO:
5579 case QAM_64:
5580 status = SetQAM64(state);
5581 break;
5582 case QAM_128:
5583 status = SetQAM128(state);
5584 break;
5585 case QAM_256:
5586 status = SetQAM256(state);
5587 break;
5588 default:
5589 status = -EINVAL;
5590 break;
5591 }
5592 if (status < 0)
5593 goto error;
5594
5595 /* Activate SCU to enable SCU commands */
5596 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5597 if (status < 0)
5598 goto error;
5599
5600 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5601 /* extAttr->currentChannel.constellation = channel->constellation; */
5602 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5603 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5604 if (status < 0)
5605 goto error;
5606
5607 /* Start processes */
5608 status = MPEGTSStart(state);
5609 if (status < 0)
5610 goto error;
5611 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5612 if (status < 0)
5613 goto error;
5614 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5615 if (status < 0)
5616 goto error;
5617 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5618 if (status < 0)
5619 goto error;
5620
5621 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5622 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5623 if (status < 0)
5624 goto error;
5625
5626 /* update global DRXK data container */
5627/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5628
5629error:
5630 if (status < 0)
5631 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005632 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005633}
5634
Oliver Endrissebc7de22011-07-03 13:49:44 -03005635static int SetQAMStandard(struct drxk_state *state,
5636 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005637{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005638 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005639#ifdef DRXK_QAM_TAPS
5640#define DRXK_QAMA_TAPS_SELECT
5641#include "drxk_filters.h"
5642#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005643#endif
5644
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005645 dprintk(1, "\n");
5646
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005647 /* added antenna switch */
5648 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005649
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005650 /* Ensure correct power-up mode */
5651 status = PowerUpQAM(state);
5652 if (status < 0)
5653 goto error;
5654 /* Reset QAM block */
5655 status = QAMResetQAM(state);
5656 if (status < 0)
5657 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005658
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005659 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005660
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005661 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5662 if (status < 0)
5663 goto error;
5664 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5665 if (status < 0)
5666 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005667
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005668 /* Upload IQM Channel Filter settings by
5669 boot loader from ROM table */
5670 switch (oMode) {
5671 case OM_QAM_ITU_A:
5672 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5673 break;
5674 case OM_QAM_ITU_C:
5675 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 -03005676 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005677 goto error;
5678 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5679 break;
5680 default:
5681 status = -EINVAL;
5682 }
5683 if (status < 0)
5684 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005685
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005686 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5687 if (status < 0)
5688 goto error;
5689 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5690 if (status < 0)
5691 goto error;
5692 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5693 if (status < 0)
5694 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005695
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005696 status = write16(state, IQM_RC_STRETCH__A, 21);
5697 if (status < 0)
5698 goto error;
5699 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5700 if (status < 0)
5701 goto error;
5702 status = write16(state, IQM_AF_CLP_TH__A, 448);
5703 if (status < 0)
5704 goto error;
5705 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5706 if (status < 0)
5707 goto error;
5708 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5709 if (status < 0)
5710 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005711
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005712 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5713 if (status < 0)
5714 goto error;
5715 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5716 if (status < 0)
5717 goto error;
5718 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5719 if (status < 0)
5720 goto error;
5721 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5722 if (status < 0)
5723 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005724
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005725 /* IQM Impulse Noise Processing Unit */
5726 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5727 if (status < 0)
5728 goto error;
5729 status = write16(state, IQM_CF_DATATH__A, 1000);
5730 if (status < 0)
5731 goto error;
5732 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5733 if (status < 0)
5734 goto error;
5735 status = write16(state, IQM_CF_DET_LCT__A, 0);
5736 if (status < 0)
5737 goto error;
5738 status = write16(state, IQM_CF_WND_LEN__A, 1);
5739 if (status < 0)
5740 goto error;
5741 status = write16(state, IQM_CF_PKDTH__A, 1);
5742 if (status < 0)
5743 goto error;
5744 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5745 if (status < 0)
5746 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005747
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005748 /* turn on IQMAF. Must be done before setAgc**() */
5749 status = SetIqmAf(state, true);
5750 if (status < 0)
5751 goto error;
5752 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5753 if (status < 0)
5754 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005755
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005756 /* IQM will not be reset from here, sync ADC and update/init AGC */
5757 status = ADCSynchronization(state);
5758 if (status < 0)
5759 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005760
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005761 /* Set the FSM step period */
5762 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5763 if (status < 0)
5764 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005765
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005766 /* Halt SCU to enable safe non-atomic accesses */
5767 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5768 if (status < 0)
5769 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005770
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005771 /* No more resets of the IQM, current standard correctly set =>
5772 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005773
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005774 status = InitAGC(state, true);
5775 if (status < 0)
5776 goto error;
5777 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5778 if (status < 0)
5779 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005780
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005781 /* Configure AGC's */
5782 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5783 if (status < 0)
5784 goto error;
5785 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5786 if (status < 0)
5787 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005788
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005789 /* Activate SCU to enable SCU commands */
5790 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5791error:
5792 if (status < 0)
5793 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005794 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005795}
5796
5797static int WriteGPIO(struct drxk_state *state)
5798{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005799 int status;
5800 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005801
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005802 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005803 /* stop lock indicator process */
5804 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5805 if (status < 0)
5806 goto error;
5807
5808 /* Write magic word to enable pdr reg write */
5809 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5810 if (status < 0)
5811 goto error;
5812
5813 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005814 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5815 /* write to io pad configuration register - output mode */
5816 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5817 if (status < 0)
5818 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005819
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005820 /* use corresponding bit in io data output registar */
5821 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5822 if (status < 0)
5823 goto error;
5824 if ((state->m_GPIO & 0x0001) == 0)
5825 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5826 else
5827 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5828 /* write back to io data output register */
5829 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5830 if (status < 0)
5831 goto error;
5832 }
5833 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5834 /* write to io pad configuration register - output mode */
5835 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5836 if (status < 0)
5837 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005838
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005839 /* use corresponding bit in io data output registar */
5840 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5841 if (status < 0)
5842 goto error;
5843 if ((state->m_GPIO & 0x0002) == 0)
5844 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5845 else
5846 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5847 /* write back to io data output register */
5848 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5849 if (status < 0)
5850 goto error;
5851 }
5852 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5853 /* write to io pad configuration register - output mode */
5854 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5855 if (status < 0)
5856 goto error;
5857
5858 /* use corresponding bit in io data output registar */
5859 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5860 if (status < 0)
5861 goto error;
5862 if ((state->m_GPIO & 0x0004) == 0)
5863 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5864 else
5865 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5866 /* write back to io data output register */
5867 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5868 if (status < 0)
5869 goto error;
5870 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005871 }
5872 /* Write magic word to disable pdr reg write */
5873 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5874error:
5875 if (status < 0)
5876 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005877 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005878}
5879
5880static int SwitchAntennaToQAM(struct drxk_state *state)
5881{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005882 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005883 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005884
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005885 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005886
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005887 if (!state->antenna_gpio)
5888 return 0;
5889
5890 gpio_state = state->m_GPIO & state->antenna_gpio;
5891
5892 if (state->antenna_dvbt ^ gpio_state) {
5893 /* Antenna is on DVB-T mode. Switch */
5894 if (state->antenna_dvbt)
5895 state->m_GPIO &= ~state->antenna_gpio;
5896 else
5897 state->m_GPIO |= state->antenna_gpio;
5898 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005899 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005900 if (status < 0)
5901 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005902 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005903}
5904
5905static int SwitchAntennaToDVBT(struct drxk_state *state)
5906{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005907 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005908 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005909
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005910 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005911
5912 if (!state->antenna_gpio)
5913 return 0;
5914
5915 gpio_state = state->m_GPIO & state->antenna_gpio;
5916
5917 if (!(state->antenna_dvbt ^ gpio_state)) {
5918 /* Antenna is on DVB-C mode. Switch */
5919 if (state->antenna_dvbt)
5920 state->m_GPIO |= state->antenna_gpio;
5921 else
5922 state->m_GPIO &= ~state->antenna_gpio;
5923 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005924 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005925 if (status < 0)
5926 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005927 return status;
5928}
5929
5930
5931static int PowerDownDevice(struct drxk_state *state)
5932{
5933 /* Power down to requested mode */
5934 /* Backup some register settings */
5935 /* Set pins with possible pull-ups connected to them in input mode */
5936 /* Analog power down */
5937 /* ADC power down */
5938 /* Power down device */
5939 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005940
5941 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005942 if (state->m_bPDownOpenBridge) {
5943 /* Open I2C bridge before power down of DRXK */
5944 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005945 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005946 goto error;
5947 }
5948 /* driver 0.9.0 */
5949 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005950 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005951 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005952
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005953 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5954 if (status < 0)
5955 goto error;
5956 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5957 if (status < 0)
5958 goto error;
5959 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5960 status = HI_CfgCommand(state);
5961error:
5962 if (status < 0)
5963 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5964
5965 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005966}
5967
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005968static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005969{
5970 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005971 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005972
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005973 dprintk(1, "\n");
5974
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005975 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5976 if (err < 0) {
5977 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005978 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005979 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005980 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005981 return err;
5982 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005983 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005984 release_firmware(fw);
5985 return err;
5986}
5987
5988static int init_drxk(struct drxk_state *state)
5989{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005990 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005991 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005992 u16 driverVersion;
5993
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005994 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005995 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005996 status = PowerUpDevice(state);
5997 if (status < 0)
5998 goto error;
5999 status = DRXX_Open(state);
6000 if (status < 0)
6001 goto error;
6002 /* Soft reset of OFDM-, sys- and osc-clockdomain */
6003 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);
6004 if (status < 0)
6005 goto error;
6006 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6007 if (status < 0)
6008 goto error;
6009 /* TODO is this needed, if yes how much delay in worst case scenario */
6010 msleep(1);
6011 state->m_DRXK_A3_PATCH_CODE = true;
6012 status = GetDeviceCapabilities(state);
6013 if (status < 0)
6014 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006015
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006016 /* Bridge delay, uses oscilator clock */
6017 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6018 /* SDA brdige delay */
6019 state->m_HICfgBridgeDelay =
6020 (u16) ((state->m_oscClockFreq / 1000) *
6021 HI_I2C_BRIDGE_DELAY) / 1000;
6022 /* Clipping */
6023 if (state->m_HICfgBridgeDelay >
6024 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006025 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006026 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6027 }
6028 /* SCL bridge delay, same as SDA for now */
6029 state->m_HICfgBridgeDelay +=
6030 state->m_HICfgBridgeDelay <<
6031 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006032
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006033 status = InitHI(state);
6034 if (status < 0)
6035 goto error;
6036 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006037#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006038 if (!(state->m_DRXK_A1_ROM_CODE)
6039 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006040#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006041 {
6042 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6043 if (status < 0)
6044 goto error;
6045 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006046
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006047 /* disable MPEG port */
6048 status = MPEGTSDisable(state);
6049 if (status < 0)
6050 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006051
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006052 /* Stop AUD and SCU */
6053 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6054 if (status < 0)
6055 goto error;
6056 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6057 if (status < 0)
6058 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006059
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006060 /* enable token-ring bus through OFDM block for possible ucode upload */
6061 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6062 if (status < 0)
6063 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006064
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006065 /* include boot loader section */
6066 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6067 if (status < 0)
6068 goto error;
6069 status = BLChainCmd(state, 0, 6, 100);
6070 if (status < 0)
6071 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006072
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006073 if (!state->microcode_name)
6074 load_microcode(state, "drxk_a3.mc");
6075 else
6076 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006077
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006078 /* disable token-ring bus through OFDM block for possible ucode upload */
6079 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6080 if (status < 0)
6081 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006082
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006083 /* Run SCU for a little while to initialize microcode version numbers */
6084 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6085 if (status < 0)
6086 goto error;
6087 status = DRXX_Open(state);
6088 if (status < 0)
6089 goto error;
6090 /* added for test */
6091 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006092
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006093 powerMode = DRXK_POWER_DOWN_OFDM;
6094 status = CtrlPowerMode(state, &powerMode);
6095 if (status < 0)
6096 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006097
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006098 /* Stamp driver version number in SCU data RAM in BCD code
6099 Done to enable field application engineers to retreive drxdriver version
6100 via I2C from SCU RAM.
6101 Not using SCU command interface for SCU register access since no
6102 microcode may be present.
6103 */
6104 driverVersion =
6105 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6106 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6107 ((DRXK_VERSION_MAJOR % 10) << 4) +
6108 (DRXK_VERSION_MINOR % 10);
6109 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6110 if (status < 0)
6111 goto error;
6112 driverVersion =
6113 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6114 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6115 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6116 (DRXK_VERSION_PATCH % 10);
6117 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6118 if (status < 0)
6119 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006120
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006121 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6122 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6123 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006124
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006125 /* Dirty fix of default values for ROM/PATCH microcode
6126 Dirty because this fix makes it impossible to setup suitable values
6127 before calling DRX_Open. This solution requires changes to RF AGC speed
6128 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006129
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006130 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006131
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006132 /* Reset driver debug flags to 0 */
6133 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6134 if (status < 0)
6135 goto error;
6136 /* driver 0.9.0 */
6137 /* Setup FEC OC:
6138 NOTE: No more full FEC resets allowed afterwards!! */
6139 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6140 if (status < 0)
6141 goto error;
6142 /* MPEGTS functions are still the same */
6143 status = MPEGTSDtoInit(state);
6144 if (status < 0)
6145 goto error;
6146 status = MPEGTSStop(state);
6147 if (status < 0)
6148 goto error;
6149 status = MPEGTSConfigurePolarity(state);
6150 if (status < 0)
6151 goto error;
6152 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6153 if (status < 0)
6154 goto error;
6155 /* added: configure GPIO */
6156 status = WriteGPIO(state);
6157 if (status < 0)
6158 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006159
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006160 state->m_DrxkState = DRXK_STOPPED;
6161
6162 if (state->m_bPowerDown) {
6163 status = PowerDownDevice(state);
6164 if (status < 0)
6165 goto error;
6166 state->m_DrxkState = DRXK_POWERED_DOWN;
6167 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006168 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006169 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006170error:
6171 if (status < 0)
6172 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006173
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006174 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006175}
6176
Oliver Endrissebc7de22011-07-03 13:49:44 -03006177static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006178{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006179 struct drxk_state *state = fe->demodulator_priv;
6180
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006181 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006182 kfree(state);
6183}
6184
Oliver Endrissebc7de22011-07-03 13:49:44 -03006185static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006186{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006187 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006188
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006189 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006190 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006191 return -EBUSY;
6192 SetOperationMode(state, OM_QAM_ITU_A);
6193 return 0;
6194}
6195
Oliver Endrissebc7de22011-07-03 13:49:44 -03006196static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006197{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006198 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006199
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006200 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006201 ShutDown(state);
6202 mutex_unlock(&state->ctlock);
6203 return 0;
6204}
6205
Oliver Endrissebc7de22011-07-03 13:49:44 -03006206static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006207{
6208 struct drxk_state *state = fe->demodulator_priv;
6209
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006210 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006211 return ConfigureI2CBridge(state, enable ? true : false);
6212}
6213
Oliver Endrissebc7de22011-07-03 13:49:44 -03006214static int drxk_set_parameters(struct dvb_frontend *fe,
6215 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006216{
6217 struct drxk_state *state = fe->demodulator_priv;
6218 u32 IF;
6219
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006220 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006221 if (fe->ops.i2c_gate_ctrl)
6222 fe->ops.i2c_gate_ctrl(fe, 1);
6223 if (fe->ops.tuner_ops.set_params)
6224 fe->ops.tuner_ops.set_params(fe, p);
6225 if (fe->ops.i2c_gate_ctrl)
6226 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006227 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006228 fe->ops.tuner_ops.get_frequency(fe, &IF);
6229 Start(state, 0, IF);
6230
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006231 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006232
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006233 return 0;
6234}
6235
Oliver Endrissebc7de22011-07-03 13:49:44 -03006236static int drxk_c_get_frontend(struct dvb_frontend *fe,
6237 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006238{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006239 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006240 return 0;
6241}
6242
6243static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6244{
6245 struct drxk_state *state = fe->demodulator_priv;
6246 u32 stat;
6247
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006248 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006249 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006250 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006251 if (stat == MPEG_LOCK)
6252 *status |= 0x1f;
6253 if (stat == FEC_LOCK)
6254 *status |= 0x0f;
6255 if (stat == DEMOD_LOCK)
6256 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006257 return 0;
6258}
6259
6260static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6261{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006262 dprintk(1, "\n");
6263
Oliver Endrissebc7de22011-07-03 13:49:44 -03006264 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006265 return 0;
6266}
6267
Oliver Endrissebc7de22011-07-03 13:49:44 -03006268static int drxk_read_signal_strength(struct dvb_frontend *fe,
6269 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006270{
6271 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006272 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006273
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006274 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006275 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006276 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006277 return 0;
6278}
6279
6280static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6281{
6282 struct drxk_state *state = fe->demodulator_priv;
6283 s32 snr2;
6284
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006285 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006286 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006287 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006288 return 0;
6289}
6290
6291static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6292{
6293 struct drxk_state *state = fe->demodulator_priv;
6294 u16 err;
6295
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006296 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006297 DVBTQAMGetAccPktErr(state, &err);
6298 *ucblocks = (u32) err;
6299 return 0;
6300}
6301
Oliver Endrissebc7de22011-07-03 13:49:44 -03006302static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6303 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006304{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006305 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006306 sets->min_delay_ms = 3000;
6307 sets->max_drift = 0;
6308 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006309 return 0;
6310}
6311
Oliver Endrissebc7de22011-07-03 13:49:44 -03006312static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006313{
Mauro Carvalho Chehabc4c3a3d2011-07-14 22:23:18 -03006314 /*
6315 * There's nothing to release here, as the state struct
6316 * is already freed by drxk_c_release.
6317 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006318}
6319
Oliver Endrissebc7de22011-07-03 13:49:44 -03006320static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006321{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006322 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006323
6324 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006325 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006326 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006327 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006328 return 0;
6329}
6330
Oliver Endrissebc7de22011-07-03 13:49:44 -03006331static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006332{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006333 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006334
6335 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006336 mutex_unlock(&state->ctlock);
6337 return 0;
6338}
6339
Oliver Endrissebc7de22011-07-03 13:49:44 -03006340static int drxk_t_get_frontend(struct dvb_frontend *fe,
6341 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006342{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006343 dprintk(1, "\n");
6344
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006345 return 0;
6346}
6347
6348static struct dvb_frontend_ops drxk_c_ops = {
6349 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006350 .name = "DRXK DVB-C",
6351 .type = FE_QAM,
6352 .frequency_stepsize = 62500,
6353 .frequency_min = 47000000,
6354 .frequency_max = 862000000,
6355 .symbol_rate_min = 870000,
6356 .symbol_rate_max = 11700000,
6357 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6358 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006359 .release = drxk_c_release,
6360 .init = drxk_c_init,
6361 .sleep = drxk_c_sleep,
6362 .i2c_gate_ctrl = drxk_gate_ctrl,
6363
6364 .set_frontend = drxk_set_parameters,
6365 .get_frontend = drxk_c_get_frontend,
6366 .get_tune_settings = drxk_c_get_tune_settings,
6367
6368 .read_status = drxk_read_status,
6369 .read_ber = drxk_read_ber,
6370 .read_signal_strength = drxk_read_signal_strength,
6371 .read_snr = drxk_read_snr,
6372 .read_ucblocks = drxk_read_ucblocks,
6373};
6374
6375static struct dvb_frontend_ops drxk_t_ops = {
6376 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006377 .name = "DRXK DVB-T",
6378 .type = FE_OFDM,
6379 .frequency_min = 47125000,
6380 .frequency_max = 865000000,
6381 .frequency_stepsize = 166667,
6382 .frequency_tolerance = 0,
6383 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6384 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6385 FE_CAN_FEC_AUTO |
6386 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6387 FE_CAN_QAM_AUTO |
6388 FE_CAN_TRANSMISSION_MODE_AUTO |
6389 FE_CAN_GUARD_INTERVAL_AUTO |
6390 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006391 .release = drxk_t_release,
6392 .init = drxk_t_init,
6393 .sleep = drxk_t_sleep,
6394 .i2c_gate_ctrl = drxk_gate_ctrl,
6395
6396 .set_frontend = drxk_set_parameters,
6397 .get_frontend = drxk_t_get_frontend,
6398
6399 .read_status = drxk_read_status,
6400 .read_ber = drxk_read_ber,
6401 .read_signal_strength = drxk_read_signal_strength,
6402 .read_snr = drxk_read_snr,
6403 .read_ucblocks = drxk_read_ucblocks,
6404};
6405
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006406struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6407 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006408 struct dvb_frontend **fe_t)
6409{
6410 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006411 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006412
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006413 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006414 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006415 if (!state)
6416 return NULL;
6417
Oliver Endrissebc7de22011-07-03 13:49:44 -03006418 state->i2c = i2c;
6419 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006420 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006421 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006422 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006423 state->antenna_gpio = config->antenna_gpio;
6424 state->antenna_dvbt = config->antenna_dvbt;
6425
6426 /* NOTE: as more UIO bits will be used, add them to the mask */
6427 state->UIO_mask = config->antenna_gpio;
6428
6429 /* Default gpio to DVB-C */
6430 if (!state->antenna_dvbt && state->antenna_gpio)
6431 state->m_GPIO |= state->antenna_gpio;
6432 else
6433 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006434
6435 mutex_init(&state->mutex);
6436 mutex_init(&state->ctlock);
6437
Oliver Endrissebc7de22011-07-03 13:49:44 -03006438 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6439 sizeof(struct dvb_frontend_ops));
6440 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6441 sizeof(struct dvb_frontend_ops));
6442 state->c_frontend.demodulator_priv = state;
6443 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006444
6445 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006446 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006447 goto error;
6448 *fe_t = &state->t_frontend;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006449
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006450 return &state->c_frontend;
6451
6452error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006453 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006454 kfree(state);
6455 return NULL;
6456}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006457EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006458
6459MODULE_DESCRIPTION("DRX-K driver");
6460MODULE_AUTHOR("Ralph Metzler");
6461MODULE_LICENSE("GPL");