blob: 5fa192731fcd34671790c5cb8f94e8800c7f7ee6 [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
Ralph Metzler43dd07f2011-07-03 13:42:18 -030094#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
95#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
96
97#ifndef DRXK_KI_RAGC_ATV
98#define DRXK_KI_RAGC_ATV 4
99#endif
100#ifndef DRXK_KI_IAGC_ATV
101#define DRXK_KI_IAGC_ATV 6
102#endif
103#ifndef DRXK_KI_DAGC_ATV
104#define DRXK_KI_DAGC_ATV 7
105#endif
106
107#ifndef DRXK_KI_RAGC_QAM
108#define DRXK_KI_RAGC_QAM 3
109#endif
110#ifndef DRXK_KI_IAGC_QAM
111#define DRXK_KI_IAGC_QAM 4
112#endif
113#ifndef DRXK_KI_DAGC_QAM
114#define DRXK_KI_DAGC_QAM 7
115#endif
116#ifndef DRXK_KI_RAGC_DVBT
117#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
118#endif
119#ifndef DRXK_KI_IAGC_DVBT
120#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
121#endif
122#ifndef DRXK_KI_DAGC_DVBT
123#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
124#endif
125
126#ifndef DRXK_AGC_DAC_OFFSET
127#define DRXK_AGC_DAC_OFFSET (0x800)
128#endif
129
130#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
131#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
132#endif
133
134#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
135#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
136#endif
137
138#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
139#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
140#endif
141
142#ifndef DRXK_QAM_SYMBOLRATE_MAX
143#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
144#endif
145
146#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
147#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
148#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
149#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
150#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
151#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
152#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
153#define DRXK_BL_ROM_OFFSET_UCODE 0
154
155#define DRXK_BLC_TIMEOUT 100
156
157#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
158#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
159
160#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
161
162#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
163#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
164#endif
165
166#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
167#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
168#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
169#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
170#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
171
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300172static unsigned int debug;
173module_param(debug, int, 0644);
174MODULE_PARM_DESC(debug, "enable debug messages");
175
176#define dprintk(level, fmt, arg...) do { \
177if (debug >= level) \
178 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
179} while (0)
180
181
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300182static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300183{
184 u64 tmp64;
185
Oliver Endrissebc7de22011-07-03 13:49:44 -0300186 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300187 do_div(tmp64, c);
188
189 return (u32) tmp64;
190}
191
192inline u32 Frac28a(u32 a, u32 c)
193{
194 int i = 0;
195 u32 Q1 = 0;
196 u32 R0 = 0;
197
Oliver Endrissebc7de22011-07-03 13:49:44 -0300198 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
199 Q1 = a / c; /* integer part, only the 4 least significant bits
200 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300201
202 /* division using radix 16, 7 nibbles in the result */
203 for (i = 0; i < 7; i++) {
204 Q1 = (Q1 << 4) | (R0 / c);
205 R0 = (R0 % c) << 4;
206 }
207 /* rounding */
208 if ((R0 >> 3) >= c)
209 Q1++;
210
211 return Q1;
212}
213
214static u32 Log10Times100(u32 x)
215{
216 static const u8 scale = 15;
217 static const u8 indexWidth = 5;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300218 u8 i = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300219 u32 y = 0;
220 u32 d = 0;
221 u32 k = 0;
222 u32 r = 0;
223 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300224 log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
225 0 <= n < ((1<<INDEXWIDTH)+1)
226 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300227
228 static const u32 log2lut[] = {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300229 0, /* 0.000000 */
230 290941, /* 290941.300628 */
231 573196, /* 573196.476418 */
232 847269, /* 847269.179851 */
233 1113620, /* 1113620.489452 */
234 1372674, /* 1372673.576986 */
235 1624818, /* 1624817.752104 */
236 1870412, /* 1870411.981536 */
237 2109788, /* 2109787.962654 */
238 2343253, /* 2343252.817465 */
239 2571091, /* 2571091.461923 */
240 2793569, /* 2793568.696416 */
241 3010931, /* 3010931.055901 */
242 3223408, /* 3223408.452106 */
243 3431216, /* 3431215.635215 */
244 3634553, /* 3634553.498355 */
245 3833610, /* 3833610.244726 */
246 4028562, /* 4028562.434393 */
247 4219576, /* 4219575.925308 */
248 4406807, /* 4406806.721144 */
249 4590402, /* 4590401.736809 */
250 4770499, /* 4770499.491025 */
251 4947231, /* 4947230.734179 */
252 5120719, /* 5120719.018555 */
253 5291081, /* 5291081.217197 */
254 5458428, /* 5458427.996830 */
255 5622864, /* 5622864.249668 */
256 5784489, /* 5784489.488298 */
257 5943398, /* 5943398.207380 */
258 6099680, /* 6099680.215452 */
259 6253421, /* 6253420.939751 */
260 6404702, /* 6404701.706649 */
261 6553600, /* 6553600.000000 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300262 };
263
264
265 if (x == 0)
Oliver Endrissebc7de22011-07-03 13:49:44 -0300266 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300267
268 /* Scale x (normalize) */
269 /* computing y in log(x/y) = log(x) - log(y) */
270 if ((x & ((0xffffffff) << (scale + 1))) == 0) {
271 for (k = scale; k > 0; k--) {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300272 if (x & (((u32) 1) << scale))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300273 break;
274 x <<= 1;
275 }
276 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300277 for (k = scale; k < 31; k++) {
278 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300279 break;
280 x >>= 1;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300281 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300282 }
283 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300284 Now x has binary point between bit[scale] and bit[scale-1]
285 and 1.0 <= x < 2.0 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300286
287 /* correction for divison: log(x) = log(x/y)+log(y) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300288 y = k * ((((u32) 1) << scale) * 200);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300289
290 /* remove integer part */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300291 x &= ((((u32) 1) << scale) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300292 /* get index */
293 i = (u8) (x >> (scale - indexWidth));
294 /* compute delta (x - a) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300295 d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300296 /* compute log, multiplication (d* (..)) must be within range ! */
297 y += log2lut[i] +
Oliver Endrissebc7de22011-07-03 13:49:44 -0300298 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300299 /* Conver to log10() */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300300 y /= 108853; /* (log2(10) << scale) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300301 r = (y >> 1);
302 /* rounding */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300303 if (y & ((u32) 1))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300304 r++;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300305 return r;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300306}
307
308/****************************************************************************/
309/* I2C **********************************************************************/
310/****************************************************************************/
311
312static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val)
313{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300314 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
315 .buf = val, .len = 1}
316 };
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300317
318 return i2c_transfer(adapter, msgs, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300319}
320
321static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
322{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300323 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300324 struct i2c_msg msg = {
325 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300326
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300327 dprintk(3, ":");
328 if (debug > 2) {
329 int i;
330 for (i = 0; i < len; i++)
331 printk(KERN_CONT " %02x", data[i]);
332 printk(KERN_CONT "\n");
333 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300334 status = i2c_transfer(adap, &msg, 1);
335 if (status >= 0 && status != 1)
336 status = -EIO;
337
338 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300339 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300340
341 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300342}
343
344static int i2c_read(struct i2c_adapter *adap,
345 u8 adr, u8 *msg, int len, u8 *answ, int alen)
346{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300347 int status;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300348 struct i2c_msg msgs[2] = {
349 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300350 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300351 {.addr = adr, .flags = I2C_M_RD,
352 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300353 };
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300354
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300355 status = i2c_transfer(adap, msgs, 2);
356 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300357 if (debug > 2)
358 printk(KERN_CONT ": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300359 if (status >= 0)
360 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300361
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300362 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300363 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300364 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300365 if (debug > 2) {
366 int i;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300367 dprintk(2, ": read from");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300368 for (i = 0; i < len; i++)
369 printk(KERN_CONT " %02x", msg[i]);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300370 printk(KERN_CONT ", value = ");
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300371 for (i = 0; i < alen; i++)
372 printk(KERN_CONT " %02x", answ[i]);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300373 printk(KERN_CONT "\n");
374 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300375 return 0;
376}
377
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300378static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300379{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300380 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300381 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300382
383 if (state->single_master)
384 flags |= 0xC0;
385
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300386 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
387 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
388 mm1[1] = ((reg >> 16) & 0xFF);
389 mm1[2] = ((reg >> 24) & 0xFF) | flags;
390 mm1[3] = ((reg >> 7) & 0xFF);
391 len = 4;
392 } else {
393 mm1[0] = ((reg << 1) & 0xFF);
394 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
395 len = 2;
396 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300397 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300398 status = i2c_read(state->i2c, adr, mm1, len, mm2, 2);
399 if (status < 0)
400 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300401 if (data)
402 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300403
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300404 return 0;
405}
406
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300407static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300408{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300409 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300410}
411
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300412static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300413{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300414 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300415 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300416
417 if (state->single_master)
418 flags |= 0xC0;
419
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300420 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
421 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
422 mm1[1] = ((reg >> 16) & 0xFF);
423 mm1[2] = ((reg >> 24) & 0xFF) | flags;
424 mm1[3] = ((reg >> 7) & 0xFF);
425 len = 4;
426 } else {
427 mm1[0] = ((reg << 1) & 0xFF);
428 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
429 len = 2;
430 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300431 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300432 status = i2c_read(state->i2c, adr, mm1, len, mm2, 4);
433 if (status < 0)
434 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300435 if (data)
436 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300437 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300438
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300439 return 0;
440}
441
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300442static int read32(struct drxk_state *state, u32 reg, u32 *data)
443{
444 return read32_flags(state, reg, data, 0);
445}
446
447static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300448{
449 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300450
451 if (state->single_master)
452 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300453 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
454 mm[0] = (((reg << 1) & 0xFF) | 0x01);
455 mm[1] = ((reg >> 16) & 0xFF);
456 mm[2] = ((reg >> 24) & 0xFF) | flags;
457 mm[3] = ((reg >> 7) & 0xFF);
458 len = 4;
459 } else {
460 mm[0] = ((reg << 1) & 0xFF);
461 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
462 len = 2;
463 }
464 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300465 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300466
467 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300468 return i2c_write(state->i2c, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300469}
470
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300471static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300472{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300473 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300474}
475
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300476static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300477{
478 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300479
480 if (state->single_master)
481 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300482 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
483 mm[0] = (((reg << 1) & 0xFF) | 0x01);
484 mm[1] = ((reg >> 16) & 0xFF);
485 mm[2] = ((reg >> 24) & 0xFF) | flags;
486 mm[3] = ((reg >> 7) & 0xFF);
487 len = 4;
488 } else {
489 mm[0] = ((reg << 1) & 0xFF);
490 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
491 len = 2;
492 }
493 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300494 mm[len + 1] = (data >> 8) & 0xff;
495 mm[len + 2] = (data >> 16) & 0xff;
496 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300497 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300498
499 return i2c_write(state->i2c, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300500}
501
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300502static int write32(struct drxk_state *state, u32 reg, u32 data)
503{
504 return write32_flags(state, reg, data, 0);
505}
506
507static int write_block(struct drxk_state *state, u32 Address,
508 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300509{
510 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300511 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300512
513 if (state->single_master)
514 Flags |= 0xC0;
515
Oliver Endrissebc7de22011-07-03 13:49:44 -0300516 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300517 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300518 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300519 u8 *AdrBuf = &state->Chunk[0];
520 u32 AdrLength = 0;
521
Oliver Endrissebc7de22011-07-03 13:49:44 -0300522 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
523 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
524 AdrBuf[1] = ((Address >> 16) & 0xFF);
525 AdrBuf[2] = ((Address >> 24) & 0xFF);
526 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300527 AdrBuf[2] |= Flags;
528 AdrLength = 4;
529 if (Chunk == state->m_ChunkSize)
530 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300531 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300532 AdrBuf[0] = ((Address << 1) & 0xFF);
533 AdrBuf[1] = (((Address >> 16) & 0x0F) |
534 ((Address >> 18) & 0xF0));
535 AdrLength = 2;
536 }
537 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300538 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
539 if (debug > 1) {
540 int i;
541 if (pBlock)
542 for (i = 0; i < Chunk; i++)
543 printk(KERN_CONT " %02x", pBlock[i]);
544 printk(KERN_CONT "\n");
545 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300546 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300547 &state->Chunk[0], Chunk + AdrLength);
548 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300549 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
550 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300551 break;
552 }
553 pBlock += Chunk;
554 Address += (Chunk >> 1);
555 BlkSize -= Chunk;
556 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300557 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300558}
559
560#ifndef DRXK_MAX_RETRIES_POWERUP
561#define DRXK_MAX_RETRIES_POWERUP 20
562#endif
563
564int PowerUpDevice(struct drxk_state *state)
565{
566 int status;
567 u8 data = 0;
568 u16 retryCount = 0;
569
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300570 dprintk(1, "\n");
571
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300572 status = i2c_read1(state->i2c, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300573 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300574 do {
575 data = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300576 status = i2c_write(state->i2c, state->demod_address,
577 &data, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300578 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300579 retryCount++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300580 if (status < 0)
581 continue;
582 status = i2c_read1(state->i2c, state->demod_address,
583 &data);
584 } while (status < 0 &&
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300585 (retryCount < DRXK_MAX_RETRIES_POWERUP));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300586 if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
587 goto error;
588 }
589
590 /* Make sure all clk domains are active */
591 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
592 if (status < 0)
593 goto error;
594 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
595 if (status < 0)
596 goto error;
597 /* Enable pll lock tests */
598 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
599 if (status < 0)
600 goto error;
601
602 state->m_currentPowerMode = DRX_POWER_UP;
603
604error:
605 if (status < 0)
606 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
607
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300608 return status;
609}
610
611
612static int init_state(struct drxk_state *state)
613{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -0300614 /*
615 * FIXME: most (all?) of the values bellow should be moved into
616 * struct drxk_config, as they are probably board-specific
617 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300618 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
619 u32 ulVSBIfAgcOutputLevel = 0;
620 u32 ulVSBIfAgcMinLevel = 0;
621 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
622 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300623
Oliver Endrissebc7de22011-07-03 13:49:44 -0300624 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
625 u32 ulVSBRfAgcOutputLevel = 0;
626 u32 ulVSBRfAgcMinLevel = 0;
627 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
628 u32 ulVSBRfAgcSpeed = 3;
629 u32 ulVSBRfAgcTop = 9500;
630 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300631
Oliver Endrissebc7de22011-07-03 13:49:44 -0300632 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
633 u32 ulATVIfAgcOutputLevel = 0;
634 u32 ulATVIfAgcMinLevel = 0;
635 u32 ulATVIfAgcMaxLevel = 0;
636 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300637
Oliver Endrissebc7de22011-07-03 13:49:44 -0300638 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
639 u32 ulATVRfAgcOutputLevel = 0;
640 u32 ulATVRfAgcMinLevel = 0;
641 u32 ulATVRfAgcMaxLevel = 0;
642 u32 ulATVRfAgcTop = 9500;
643 u32 ulATVRfAgcCutOffCurrent = 4000;
644 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300645
646 u32 ulQual83 = DEFAULT_MER_83;
647 u32 ulQual93 = DEFAULT_MER_93;
648
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300649 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
650 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
651
652 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
653 /* io_pad_cfg_mode output mode is drive always */
654 /* io_pad_cfg_drive is set to power 2 (23 mA) */
655 u32 ulGPIOCfg = 0x0113;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300656 u32 ulInvertTSClock = 0;
657 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300658 u32 ulDVBTBitrate = 50000000;
659 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
660
661 u32 ulInsertRSByte = 0;
662
663 u32 ulRfMirror = 1;
664 u32 ulPowerDown = 0;
665
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300666 dprintk(1, "\n");
667
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300668 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300669 state->m_hasDVBT = false;
670 state->m_hasDVBC = false;
671 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300672 state->m_hasOOB = false;
673 state->m_hasAudio = false;
674
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -0300675 if (!state->m_ChunkSize)
Mauro Carvalho Chehabde724052011-11-20 11:23:24 -0200676 state->m_ChunkSize = 124;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300677
678 state->m_oscClockFreq = 0;
679 state->m_smartAntInverted = false;
680 state->m_bPDownOpenBridge = false;
681
682 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300683 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300684 /* Timing div, 250ns/Psys */
685 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
686 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
687 HI_I2C_DELAY) / 1000;
688 /* Clipping */
689 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
690 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
691 state->m_HICfgWakeUpKey = (state->demod_address << 1);
692 /* port/bridge/power down ctrl */
693 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
694
695 state->m_bPowerDown = (ulPowerDown != 0);
696
697 state->m_DRXK_A1_PATCH_CODE = false;
698 state->m_DRXK_A1_ROM_CODE = false;
699 state->m_DRXK_A2_ROM_CODE = false;
700 state->m_DRXK_A3_ROM_CODE = false;
701 state->m_DRXK_A2_PATCH_CODE = false;
702 state->m_DRXK_A3_PATCH_CODE = false;
703
704 /* Init AGC and PGA parameters */
705 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300706 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
707 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
708 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
709 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
710 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300711 state->m_vsbPgaCfg = 140;
712
713 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300714 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
715 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
716 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
717 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
718 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
719 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
720 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
721 state->m_vsbPreSawCfg.reference = 0x07;
722 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300723
724 state->m_Quality83percent = DEFAULT_MER_83;
725 state->m_Quality93percent = DEFAULT_MER_93;
726 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
727 state->m_Quality83percent = ulQual83;
728 state->m_Quality93percent = ulQual93;
729 }
730
731 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300732 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
733 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
734 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
735 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
736 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300737
738 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300739 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
740 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
741 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
742 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
743 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
744 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
745 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
746 state->m_atvPreSawCfg.reference = 0x04;
747 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300748
749
750 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300751 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
752 state->m_dvbtRfAgcCfg.outputLevel = 0;
753 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
754 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
755 state->m_dvbtRfAgcCfg.top = 0x2100;
756 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
757 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300758
759
760 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300761 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
762 state->m_dvbtIfAgcCfg.outputLevel = 0;
763 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
764 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
765 state->m_dvbtIfAgcCfg.top = 13424;
766 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
767 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300768 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300769 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
770 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300771
Oliver Endrissebc7de22011-07-03 13:49:44 -0300772 state->m_dvbtPreSawCfg.reference = 4;
773 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300774
775 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300776 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
777 state->m_qamRfAgcCfg.outputLevel = 0;
778 state->m_qamRfAgcCfg.minOutputLevel = 6023;
779 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
780 state->m_qamRfAgcCfg.top = 0x2380;
781 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
782 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300783
784 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300785 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
786 state->m_qamIfAgcCfg.outputLevel = 0;
787 state->m_qamIfAgcCfg.minOutputLevel = 0;
788 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
789 state->m_qamIfAgcCfg.top = 0x0511;
790 state->m_qamIfAgcCfg.cutOffCurrent = 0;
791 state->m_qamIfAgcCfg.speed = 3;
792 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300793 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
794
Oliver Endrissebc7de22011-07-03 13:49:44 -0300795 state->m_qamPgaCfg = 140;
796 state->m_qamPreSawCfg.reference = 4;
797 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300798
799 state->m_OperationMode = OM_NONE;
800 state->m_DrxkState = DRXK_UNINITIALIZED;
801
802 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300803 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
804 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300805 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
806 state->m_invertERR = false; /* If TRUE; invert ERR signal */
807 state->m_invertSTR = false; /* If TRUE; invert STR signals */
808 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
809 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -0300810
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300811 /* If TRUE; static MPEG clockrate will be used;
812 otherwise clockrate will adapt to the bitrate of the TS */
813
814 state->m_DVBTBitrate = ulDVBTBitrate;
815 state->m_DVBCBitrate = ulDVBCBitrate;
816
817 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300818
819 /* Maximum bitrate in b/s in case static clockrate is selected */
820 state->m_mpegTsStaticBitrate = 19392658;
821 state->m_disableTEIhandling = false;
822
823 if (ulInsertRSByte)
824 state->m_insertRSByte = true;
825
826 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
827 if (ulMpegLockTimeOut < 10000)
828 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
829 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
830 if (ulDemodLockTimeOut < 10000)
831 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
832
Oliver Endrissebc7de22011-07-03 13:49:44 -0300833 /* QAM defaults */
834 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300835 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300836 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
837 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300838
839 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
840 state->m_agcFastClipCtrlDelay = 0;
841
842 state->m_GPIOCfg = (ulGPIOCfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300843
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300844 state->m_bPowerDown = false;
845 state->m_currentPowerMode = DRX_POWER_DOWN;
846
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300847 state->m_rfmirror = (ulRfMirror == 0);
848 state->m_IfAgcPol = false;
849 return 0;
850}
851
852static int DRXX_Open(struct drxk_state *state)
853{
854 int status = 0;
855 u32 jtag = 0;
856 u16 bid = 0;
857 u16 key = 0;
858
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300859 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300860 /* stop lock indicator process */
861 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
862 if (status < 0)
863 goto error;
864 /* Check device id */
865 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
866 if (status < 0)
867 goto error;
868 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
869 if (status < 0)
870 goto error;
871 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
872 if (status < 0)
873 goto error;
874 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
875 if (status < 0)
876 goto error;
877 status = write16(state, SIO_TOP_COMM_KEY__A, key);
878error:
879 if (status < 0)
880 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300881 return status;
882}
883
884static int GetDeviceCapabilities(struct drxk_state *state)
885{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300886 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300887 u32 sioTopJtagidLo = 0;
888 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300889 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300890
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300891 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300892
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300893 /* driver 0.9.0 */
894 /* stop lock indicator process */
895 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
896 if (status < 0)
897 goto error;
898 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
899 if (status < 0)
900 goto error;
901 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
902 if (status < 0)
903 goto error;
904 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
905 if (status < 0)
906 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300907
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300908 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
909 case 0:
910 /* ignore (bypass ?) */
911 break;
912 case 1:
913 /* 27 MHz */
914 state->m_oscClockFreq = 27000;
915 break;
916 case 2:
917 /* 20.25 MHz */
918 state->m_oscClockFreq = 20250;
919 break;
920 case 3:
921 /* 4 MHz */
922 state->m_oscClockFreq = 20250;
923 break;
924 default:
925 printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
926 return -EINVAL;
927 }
928 /*
929 Determine device capabilities
930 Based on pinning v14
931 */
932 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
933 if (status < 0)
934 goto error;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300935
936printk(KERN_ERR "drxk: status = 0x%08x\n", sioTopJtagidLo);
937
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300938 /* driver 0.9.0 */
939 switch ((sioTopJtagidLo >> 29) & 0xF) {
940 case 0:
941 state->m_deviceSpin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300942 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300943 break;
944 case 2:
945 state->m_deviceSpin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300946 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300947 break;
948 case 3:
949 state->m_deviceSpin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300950 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300951 break;
952 default:
953 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
954 status = -EINVAL;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300955 printk(KERN_ERR "drxk: Spin %d unknown\n",
956 (sioTopJtagidLo >> 29) & 0xF);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300957 goto error2;
958 }
959 switch ((sioTopJtagidLo >> 12) & 0xFF) {
960 case 0x13:
961 /* typeId = DRX3913K_TYPE_ID */
962 state->m_hasLNA = false;
963 state->m_hasOOB = false;
964 state->m_hasATV = false;
965 state->m_hasAudio = false;
966 state->m_hasDVBT = true;
967 state->m_hasDVBC = true;
968 state->m_hasSAWSW = true;
969 state->m_hasGPIO2 = false;
970 state->m_hasGPIO1 = false;
971 state->m_hasIRQN = false;
972 break;
973 case 0x15:
974 /* typeId = DRX3915K_TYPE_ID */
975 state->m_hasLNA = false;
976 state->m_hasOOB = false;
977 state->m_hasATV = true;
978 state->m_hasAudio = false;
979 state->m_hasDVBT = true;
980 state->m_hasDVBC = false;
981 state->m_hasSAWSW = true;
982 state->m_hasGPIO2 = true;
983 state->m_hasGPIO1 = true;
984 state->m_hasIRQN = false;
985 break;
986 case 0x16:
987 /* typeId = DRX3916K_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 0x18:
1000 /* typeId = DRX3918K_TYPE_ID */
1001 state->m_hasLNA = false;
1002 state->m_hasOOB = false;
1003 state->m_hasATV = true;
1004 state->m_hasAudio = true;
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 0x21:
1013 /* typeId = DRX3921K_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 = true;
1020 state->m_hasSAWSW = true;
1021 state->m_hasGPIO2 = true;
1022 state->m_hasGPIO1 = true;
1023 state->m_hasIRQN = false;
1024 break;
1025 case 0x23:
1026 /* typeId = DRX3923K_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 0x25:
1039 /* typeId = DRX3925K_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 0x26:
1052 /* typeId = DRX3926K_TYPE_ID */
1053 state->m_hasLNA = false;
1054 state->m_hasOOB = false;
1055 state->m_hasATV = true;
1056 state->m_hasAudio = false;
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 default:
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -03001065 printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001066 ((sioTopJtagidLo >> 12) & 0xFF));
1067 status = -EINVAL;
1068 goto error2;
1069 }
1070
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -03001071 printk(KERN_INFO
1072 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
1073 ((sioTopJtagidLo >> 12) & 0xFF), spin,
1074 state->m_oscClockFreq / 1000,
1075 state->m_oscClockFreq % 1000);
1076
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001077error:
1078 if (status < 0)
1079 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1080
1081error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001082 return status;
1083}
1084
1085static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1086{
1087 int status;
1088 bool powerdown_cmd;
1089
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001090 dprintk(1, "\n");
1091
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001092 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001093 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001094 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001095 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001096 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1097 msleep(1);
1098
1099 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001100 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1101 ((state->m_HICfgCtrl) &
1102 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1103 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001104 if (powerdown_cmd == false) {
1105 /* Wait until command rdy */
1106 u32 retryCount = 0;
1107 u16 waitCmd;
1108
1109 do {
1110 msleep(1);
1111 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001112 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1113 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001114 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1115 && (waitCmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001116 if (status < 0)
1117 goto error;
1118 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001119 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001120error:
1121 if (status < 0)
1122 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1123
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001124 return status;
1125}
1126
1127static int HI_CfgCommand(struct drxk_state *state)
1128{
1129 int status;
1130
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001131 dprintk(1, "\n");
1132
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001133 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001134
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001135 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1136 if (status < 0)
1137 goto error;
1138 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1139 if (status < 0)
1140 goto error;
1141 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1142 if (status < 0)
1143 goto error;
1144 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1145 if (status < 0)
1146 goto error;
1147 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1148 if (status < 0)
1149 goto error;
1150 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1151 if (status < 0)
1152 goto error;
1153 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1154 if (status < 0)
1155 goto error;
1156
1157 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1158error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001159 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001160 if (status < 0)
1161 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001162 return status;
1163}
1164
1165static int InitHI(struct drxk_state *state)
1166{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001167 dprintk(1, "\n");
1168
Oliver Endrissebc7de22011-07-03 13:49:44 -03001169 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001170 state->m_HICfgTimeout = 0x96FF;
1171 /* port/bridge/power down ctrl */
1172 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001173
Oliver Endrissebc7de22011-07-03 13:49:44 -03001174 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001175}
1176
1177static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1178{
1179 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001180 u16 sioPdrMclkCfg = 0;
1181 u16 sioPdrMdxCfg = 0;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001182 u16 err_cfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001183
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03001184 dprintk(1, ": mpeg %s, %s mode\n",
1185 mpegEnable ? "enable" : "disable",
1186 state->m_enableParallel ? "parallel" : "serial");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001187
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001188 /* stop lock indicator process */
1189 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1190 if (status < 0)
1191 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001192
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001193 /* MPEG TS pad configuration */
1194 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1195 if (status < 0)
1196 goto error;
1197
1198 if (mpegEnable == false) {
1199 /* Set MPEG TS pads to inputmode */
1200 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1201 if (status < 0)
1202 goto error;
1203 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1204 if (status < 0)
1205 goto error;
1206 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1207 if (status < 0)
1208 goto error;
1209 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1210 if (status < 0)
1211 goto error;
1212 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1213 if (status < 0)
1214 goto error;
1215 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1216 if (status < 0)
1217 goto error;
1218 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1219 if (status < 0)
1220 goto error;
1221 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1222 if (status < 0)
1223 goto error;
1224 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1225 if (status < 0)
1226 goto error;
1227 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1228 if (status < 0)
1229 goto error;
1230 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1231 if (status < 0)
1232 goto error;
1233 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1234 if (status < 0)
1235 goto error;
1236 } else {
1237 /* Enable MPEG output */
1238 sioPdrMdxCfg =
1239 ((state->m_TSDataStrength <<
1240 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1241 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1242 SIO_PDR_MCLK_CFG_DRIVE__B) |
1243 0x0003);
1244
1245 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1246 if (status < 0)
1247 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001248
1249 if (state->enable_merr_cfg)
1250 err_cfg = sioPdrMdxCfg;
1251
1252 status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001253 if (status < 0)
1254 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001255 status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001256 if (status < 0)
1257 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001258
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001259 if (state->m_enableParallel == true) {
1260 /* paralel -> enable MD1 to MD7 */
1261 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001262 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001263 goto error;
1264 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001265 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001266 goto error;
1267 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001268 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001269 goto error;
1270 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001271 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001272 goto error;
1273 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001274 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001275 goto error;
1276 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1277 if (status < 0)
1278 goto error;
1279 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1280 if (status < 0)
1281 goto error;
1282 } else {
1283 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1284 SIO_PDR_MD0_CFG_DRIVE__B)
1285 | 0x0003);
1286 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001287 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001288 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001289 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001290 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001291 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001292 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001293 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001294 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001295 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001296 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001297 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001298 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001299 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001300 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001301 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001302 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001303 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001304 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001305 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001306 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001307 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001308 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001309 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001310 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001311 goto error;
1312 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001313 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001314 goto error;
1315 }
1316 /* Enable MB output over MPEG pads and ctl input */
1317 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1318 if (status < 0)
1319 goto error;
1320 /* Write nomagic word to enable pdr reg write */
1321 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1322error:
1323 if (status < 0)
1324 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001325 return status;
1326}
1327
1328static int MPEGTSDisable(struct drxk_state *state)
1329{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001330 dprintk(1, "\n");
1331
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001332 return MPEGTSConfigurePins(state, false);
1333}
1334
1335static int BLChainCmd(struct drxk_state *state,
1336 u16 romOffset, u16 nrOfElements, u32 timeOut)
1337{
1338 u16 blStatus = 0;
1339 int status;
1340 unsigned long end;
1341
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001342 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001343 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001344 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1345 if (status < 0)
1346 goto error;
1347 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1348 if (status < 0)
1349 goto error;
1350 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1351 if (status < 0)
1352 goto error;
1353 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1354 if (status < 0)
1355 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001356
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001357 end = jiffies + msecs_to_jiffies(timeOut);
1358 do {
1359 msleep(1);
1360 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1361 if (status < 0)
1362 goto error;
1363 } while ((blStatus == 0x1) &&
1364 ((time_is_after_jiffies(end))));
1365
1366 if (blStatus == 0x1) {
1367 printk(KERN_ERR "drxk: SIO not ready\n");
1368 status = -EINVAL;
1369 goto error2;
1370 }
1371error:
1372 if (status < 0)
1373 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1374error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001375 mutex_unlock(&state->mutex);
1376 return status;
1377}
1378
1379
1380static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001381 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001382{
1383 const u8 *pSrc = pMCImage;
1384 u16 Flags;
1385 u16 Drain;
1386 u32 Address;
1387 u16 nBlocks;
1388 u16 BlockSize;
1389 u16 BlockCRC;
1390 u32 offset = 0;
1391 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001392 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001393
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001394 dprintk(1, "\n");
1395
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001396 /* down the drain (we don care about MAGIC_WORD) */
1397 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001398 pSrc += sizeof(u16);
1399 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001400 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001401 pSrc += sizeof(u16);
1402 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001403
1404 for (i = 0; i < nBlocks; i += 1) {
1405 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001406 (pSrc[2] << 8) | pSrc[3];
1407 pSrc += sizeof(u32);
1408 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001409
1410 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001411 pSrc += sizeof(u16);
1412 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001413
1414 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001415 pSrc += sizeof(u16);
1416 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001417
1418 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001419 pSrc += sizeof(u16);
1420 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001421
1422 if (offset + BlockSize > Length) {
1423 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1424 return -EINVAL;
1425 }
1426
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001427 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001428 if (status < 0) {
1429 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001430 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001431 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001432 pSrc += BlockSize;
1433 offset += BlockSize;
1434 }
1435 return status;
1436}
1437
1438static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1439{
1440 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001441 u16 data = 0;
1442 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001443 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1444 unsigned long end;
1445
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001446 dprintk(1, "\n");
1447
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001448 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001449 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001450 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1451 }
1452
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001453 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1454 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001455 /* tokenring already has correct status */
1456 return status;
1457 }
1458 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001459 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001460
Oliver Endrissebc7de22011-07-03 13:49:44 -03001461 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001462 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001463 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001464 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001465 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001466 msleep(1);
1467 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001468 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001469 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001470 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001471 }
1472 return status;
1473}
1474
1475static int MPEGTSStop(struct drxk_state *state)
1476{
1477 int status = 0;
1478 u16 fecOcSncMode = 0;
1479 u16 fecOcIprMode = 0;
1480
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001481 dprintk(1, "\n");
1482
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001483 /* Gracefull shutdown (byte boundaries) */
1484 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1485 if (status < 0)
1486 goto error;
1487 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1488 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1489 if (status < 0)
1490 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001491
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001492 /* Suppress MCLK during absence of data */
1493 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1494 if (status < 0)
1495 goto error;
1496 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1497 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1498
1499error:
1500 if (status < 0)
1501 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1502
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001503 return status;
1504}
1505
1506static int scu_command(struct drxk_state *state,
1507 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001508 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001509{
1510#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1511#error DRXK register mapping no longer compatible with this routine!
1512#endif
1513 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001514 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001515 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001516 u8 buffer[34];
1517 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001518 const char *p;
1519 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001520
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001521 dprintk(1, "\n");
1522
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001523 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1524 ((resultLen > 0) && (result == NULL)))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001525 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001526
1527 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001528
1529 /* assume that the command register is ready
1530 since it is checked afterwards */
1531 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1532 buffer[cnt++] = (parameter[ii] & 0xFF);
1533 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1534 }
1535 buffer[cnt++] = (cmd & 0xFF);
1536 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1537
1538 write_block(state, SCU_RAM_PARAM_0__A -
1539 (parameterLen - 1), cnt, buffer);
1540 /* Wait until SCU has processed command */
1541 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001542 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001543 msleep(1);
1544 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1545 if (status < 0)
1546 goto error;
1547 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1548 if (curCmd != DRX_SCU_READY) {
1549 printk(KERN_ERR "drxk: SCU not ready\n");
1550 status = -EIO;
1551 goto error2;
1552 }
1553 /* read results */
1554 if ((resultLen > 0) && (result != NULL)) {
1555 s16 err;
1556 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001557
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001558 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1559 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001560 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001561 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001562 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001563
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001564 /* Check if an error was reported by SCU */
1565 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001566 if (err >= 0)
1567 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001568
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001569 /* check for the known error codes */
1570 switch (err) {
1571 case SCU_RESULT_UNKCMD:
1572 p = "SCU_RESULT_UNKCMD";
1573 break;
1574 case SCU_RESULT_UNKSTD:
1575 p = "SCU_RESULT_UNKSTD";
1576 break;
1577 case SCU_RESULT_SIZE:
1578 p = "SCU_RESULT_SIZE";
1579 break;
1580 case SCU_RESULT_INVPAR:
1581 p = "SCU_RESULT_INVPAR";
1582 break;
1583 default: /* Other negative values are errors */
1584 sprintf(errname, "ERROR: %d\n", err);
1585 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001586 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001587 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1588 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1589 status = -EINVAL;
1590 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001591 }
1592
1593error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001594 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001595 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001596error2:
1597 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001598 return status;
1599}
1600
1601static int SetIqmAf(struct drxk_state *state, bool active)
1602{
1603 u16 data = 0;
1604 int status;
1605
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001606 dprintk(1, "\n");
1607
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001608 /* Configure IQM */
1609 status = read16(state, IQM_AF_STDBY__A, &data);
1610 if (status < 0)
1611 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001612
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001613 if (!active) {
1614 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1615 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1616 | IQM_AF_STDBY_STDBY_PD_STANDBY
1617 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1618 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1619 } else {
1620 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1621 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1622 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1623 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1624 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1625 );
1626 }
1627 status = write16(state, IQM_AF_STDBY__A, data);
1628
1629error:
1630 if (status < 0)
1631 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001632 return status;
1633}
1634
Oliver Endrissebc7de22011-07-03 13:49:44 -03001635static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001636{
1637 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001638 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001639
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001640 dprintk(1, "\n");
1641
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001642 /* Check arguments */
1643 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001644 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001645
1646 switch (*mode) {
1647 case DRX_POWER_UP:
1648 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1649 break;
1650 case DRXK_POWER_DOWN_OFDM:
1651 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1652 break;
1653 case DRXK_POWER_DOWN_CORE:
1654 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1655 break;
1656 case DRXK_POWER_DOWN_PLL:
1657 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1658 break;
1659 case DRX_POWER_DOWN:
1660 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1661 break;
1662 default:
1663 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001664 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001665 }
1666
1667 /* If already in requested power mode, do nothing */
1668 if (state->m_currentPowerMode == *mode)
1669 return 0;
1670
1671 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001672 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001673 status = PowerUpDevice(state);
1674 if (status < 0)
1675 goto error;
1676 status = DVBTEnableOFDMTokenRing(state, true);
1677 if (status < 0)
1678 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001679 }
1680
1681 if (*mode == DRX_POWER_UP) {
1682 /* Restore analog & pin configuartion */
1683 } else {
1684 /* Power down to requested mode */
1685 /* Backup some register settings */
1686 /* Set pins with possible pull-ups connected
1687 to them in input mode */
1688 /* Analog power down */
1689 /* ADC power down */
1690 /* Power down device */
1691 /* stop all comm_exec */
1692 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001693 switch (state->m_OperationMode) {
1694 case OM_DVBT:
1695 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001696 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001697 goto error;
1698 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001699 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001700 goto error;
1701 break;
1702 case OM_QAM_ITU_A:
1703 case OM_QAM_ITU_C:
1704 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001705 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001706 goto error;
1707 status = PowerDownQAM(state);
1708 if (status < 0)
1709 goto error;
1710 break;
1711 default:
1712 break;
1713 }
1714 status = DVBTEnableOFDMTokenRing(state, false);
1715 if (status < 0)
1716 goto error;
1717 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1718 if (status < 0)
1719 goto error;
1720 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1721 if (status < 0)
1722 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001723
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001724 if (*mode != DRXK_POWER_DOWN_OFDM) {
1725 state->m_HICfgCtrl |=
1726 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1727 status = HI_CfgCommand(state);
1728 if (status < 0)
1729 goto error;
1730 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001731 }
1732 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001733
1734error:
1735 if (status < 0)
1736 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1737
Oliver Endrissebc7de22011-07-03 13:49:44 -03001738 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001739}
1740
1741static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1742{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001743 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001744 u16 cmdResult = 0;
1745 u16 data = 0;
1746 int status;
1747
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001748 dprintk(1, "\n");
1749
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001750 status = read16(state, SCU_COMM_EXEC__A, &data);
1751 if (status < 0)
1752 goto error;
1753 if (data == SCU_COMM_EXEC_ACTIVE) {
1754 /* Send OFDM stop command */
1755 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 -03001756 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001757 goto error;
1758 /* Send OFDM reset command */
1759 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1760 if (status < 0)
1761 goto error;
1762 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001763
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001764 /* Reset datapath for OFDM, processors first */
1765 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1766 if (status < 0)
1767 goto error;
1768 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1769 if (status < 0)
1770 goto error;
1771 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1772 if (status < 0)
1773 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001774
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001775 /* powerdown AFE */
1776 status = SetIqmAf(state, false);
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 to OFDM mode */
1781 if (setPowerMode) {
1782 status = CtrlPowerMode(state, &powerMode);
1783 if (status < 0)
1784 goto error;
1785 }
1786error:
1787 if (status < 0)
1788 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001789 return status;
1790}
1791
Oliver Endrissebc7de22011-07-03 13:49:44 -03001792static int SetOperationMode(struct drxk_state *state,
1793 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001794{
1795 int status = 0;
1796
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001797 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001798 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001799 Stop and power down previous standard
1800 TODO investigate total power down instead of partial
1801 power down depending on "previous" standard.
1802 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001803
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001804 /* disable HW lock indicator */
1805 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1806 if (status < 0)
1807 goto error;
1808
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001809 /* Device is already at the required mode */
1810 if (state->m_OperationMode == oMode)
1811 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001812
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001813 switch (state->m_OperationMode) {
1814 /* OM_NONE was added for start up */
1815 case OM_NONE:
1816 break;
1817 case OM_DVBT:
1818 status = MPEGTSStop(state);
1819 if (status < 0)
1820 goto error;
1821 status = PowerDownDVBT(state, true);
1822 if (status < 0)
1823 goto error;
1824 state->m_OperationMode = OM_NONE;
1825 break;
1826 case OM_QAM_ITU_A: /* fallthrough */
1827 case OM_QAM_ITU_C:
1828 status = MPEGTSStop(state);
1829 if (status < 0)
1830 goto error;
1831 status = PowerDownQAM(state);
1832 if (status < 0)
1833 goto error;
1834 state->m_OperationMode = OM_NONE;
1835 break;
1836 case OM_QAM_ITU_B:
1837 default:
1838 status = -EINVAL;
1839 goto error;
1840 }
1841
1842 /*
1843 Power up new standard
1844 */
1845 switch (oMode) {
1846 case OM_DVBT:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001847 dprintk(1, ": DVB-T\n");
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001848 state->m_OperationMode = oMode;
1849 status = SetDVBTStandard(state, oMode);
1850 if (status < 0)
1851 goto error;
1852 break;
1853 case OM_QAM_ITU_A: /* fallthrough */
1854 case OM_QAM_ITU_C:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001855 dprintk(1, ": DVB-C Annex %c\n",
1856 (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001857 state->m_OperationMode = oMode;
1858 status = SetQAMStandard(state, oMode);
1859 if (status < 0)
1860 goto error;
1861 break;
1862 case OM_QAM_ITU_B:
1863 default:
1864 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001865 }
1866error:
1867 if (status < 0)
1868 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1869 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001870}
1871
1872static int Start(struct drxk_state *state, s32 offsetFreq,
1873 s32 IntermediateFrequency)
1874{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001875 int status = -EINVAL;
1876
1877 u16 IFreqkHz;
1878 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001879
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001880 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001881 if (state->m_DrxkState != DRXK_STOPPED &&
1882 state->m_DrxkState != DRXK_DTV_STARTED)
1883 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001884
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03001885 state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001886
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001887 if (IntermediateFrequency < 0) {
1888 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1889 IntermediateFrequency = -IntermediateFrequency;
1890 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001891
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001892 switch (state->m_OperationMode) {
1893 case OM_QAM_ITU_A:
1894 case OM_QAM_ITU_C:
1895 IFreqkHz = (IntermediateFrequency / 1000);
1896 status = SetQAM(state, IFreqkHz, OffsetkHz);
1897 if (status < 0)
1898 goto error;
1899 state->m_DrxkState = DRXK_DTV_STARTED;
1900 break;
1901 case OM_DVBT:
1902 IFreqkHz = (IntermediateFrequency / 1000);
1903 status = MPEGTSStop(state);
1904 if (status < 0)
1905 goto error;
1906 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1907 if (status < 0)
1908 goto error;
1909 status = DVBTStart(state);
1910 if (status < 0)
1911 goto error;
1912 state->m_DrxkState = DRXK_DTV_STARTED;
1913 break;
1914 default:
1915 break;
1916 }
1917error:
1918 if (status < 0)
1919 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001920 return status;
1921}
1922
1923static int ShutDown(struct drxk_state *state)
1924{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001925 dprintk(1, "\n");
1926
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001927 MPEGTSStop(state);
1928 return 0;
1929}
1930
Oliver Endrissebc7de22011-07-03 13:49:44 -03001931static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1932 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001933{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001934 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001935
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001936 dprintk(1, "\n");
1937
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001938 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001939 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001940
1941 *pLockStatus = NOT_LOCKED;
1942
1943 /* define the SCU command code */
1944 switch (state->m_OperationMode) {
1945 case OM_QAM_ITU_A:
1946 case OM_QAM_ITU_B:
1947 case OM_QAM_ITU_C:
1948 status = GetQAMLockStatus(state, pLockStatus);
1949 break;
1950 case OM_DVBT:
1951 status = GetDVBTLockStatus(state, pLockStatus);
1952 break;
1953 default:
1954 break;
1955 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001956error:
1957 if (status < 0)
1958 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001959 return status;
1960}
1961
1962static int MPEGTSStart(struct drxk_state *state)
1963{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001964 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001965
1966 u16 fecOcSncMode = 0;
1967
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001968 /* Allow OC to sync again */
1969 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1970 if (status < 0)
1971 goto error;
1972 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1973 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1974 if (status < 0)
1975 goto error;
1976 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1977error:
1978 if (status < 0)
1979 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001980 return status;
1981}
1982
1983static int MPEGTSDtoInit(struct drxk_state *state)
1984{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001985 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001986
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001987 dprintk(1, "\n");
1988
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001989 /* Rate integration settings */
1990 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1991 if (status < 0)
1992 goto error;
1993 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1994 if (status < 0)
1995 goto error;
1996 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1997 if (status < 0)
1998 goto error;
1999 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
2000 if (status < 0)
2001 goto error;
2002 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2003 if (status < 0)
2004 goto error;
2005 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2006 if (status < 0)
2007 goto error;
2008 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2009 if (status < 0)
2010 goto error;
2011 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2012 if (status < 0)
2013 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002014
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002015 /* Additional configuration */
2016 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2017 if (status < 0)
2018 goto error;
2019 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2020 if (status < 0)
2021 goto error;
2022 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2023error:
2024 if (status < 0)
2025 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2026
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002027 return status;
2028}
2029
Oliver Endrissebc7de22011-07-03 13:49:44 -03002030static int MPEGTSDtoSetup(struct drxk_state *state,
2031 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002032{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002033 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002034
Oliver Endrissebc7de22011-07-03 13:49:44 -03002035 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2036 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2037 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2038 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2039 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2040 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2041 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002042 u16 fecOcTmdMode = 0;
2043 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002044 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002045 bool staticCLK = false;
2046
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002047 dprintk(1, "\n");
2048
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002049 /* Check insertion of the Reed-Solomon parity bytes */
2050 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2051 if (status < 0)
2052 goto error;
2053 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2054 if (status < 0)
2055 goto error;
2056 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2057 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2058 if (state->m_insertRSByte == true) {
2059 /* enable parity symbol forward */
2060 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2061 /* MVAL disable during parity bytes */
2062 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2063 /* TS burst length to 204 */
2064 fecOcDtoBurstLen = 204;
2065 }
2066
2067 /* Check serial or parrallel output */
2068 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2069 if (state->m_enableParallel == false) {
2070 /* MPEG data output is serial -> set ipr_mode[0] */
2071 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2072 }
2073
2074 switch (oMode) {
2075 case OM_DVBT:
2076 maxBitRate = state->m_DVBTBitrate;
2077 fecOcTmdMode = 3;
2078 fecOcRcnCtlRate = 0xC00000;
2079 staticCLK = state->m_DVBTStaticCLK;
2080 break;
2081 case OM_QAM_ITU_A: /* fallthrough */
2082 case OM_QAM_ITU_C:
2083 fecOcTmdMode = 0x0004;
2084 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2085 maxBitRate = state->m_DVBCBitrate;
2086 staticCLK = state->m_DVBCStaticCLK;
2087 break;
2088 default:
2089 status = -EINVAL;
2090 } /* switch (standard) */
2091 if (status < 0)
2092 goto error;
2093
2094 /* Configure DTO's */
2095 if (staticCLK) {
2096 u32 bitRate = 0;
2097
2098 /* Rational DTO for MCLK source (static MCLK rate),
2099 Dynamic DTO for optimal grouping
2100 (avoid intra-packet gaps),
2101 DTO offset enable to sync TS burst with MSTRT */
2102 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2103 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2104 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2105 FEC_OC_FCT_MODE_VIRT_ENA__M);
2106
2107 /* Check user defined bitrate */
2108 bitRate = maxBitRate;
2109 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2110 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002111 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002112 /* Rational DTO period:
2113 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002114
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002115 Result should be floored,
2116 to make sure >= requested bitrate
2117 */
2118 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2119 * 1000) / bitRate);
2120 if (fecOcDtoPeriod <= 2)
2121 fecOcDtoPeriod = 0;
2122 else
2123 fecOcDtoPeriod -= 2;
2124 fecOcTmdIntUpdRate = 8;
2125 } else {
2126 /* (commonAttr->staticCLK == false) => dynamic mode */
2127 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2128 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2129 fecOcTmdIntUpdRate = 5;
2130 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002131
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002132 /* Write appropriate registers with requested configuration */
2133 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2134 if (status < 0)
2135 goto error;
2136 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2137 if (status < 0)
2138 goto error;
2139 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2140 if (status < 0)
2141 goto error;
2142 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2143 if (status < 0)
2144 goto error;
2145 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2146 if (status < 0)
2147 goto error;
2148 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2149 if (status < 0)
2150 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002151
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002152 /* Rate integration settings */
2153 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2154 if (status < 0)
2155 goto error;
2156 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2157 if (status < 0)
2158 goto error;
2159 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2160error:
2161 if (status < 0)
2162 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002163 return status;
2164}
2165
2166static int MPEGTSConfigurePolarity(struct drxk_state *state)
2167{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002168 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002169
2170 /* Data mask for the output data byte */
2171 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002172 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2173 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2174 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2175 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002176
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002177 dprintk(1, "\n");
2178
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002179 /* Control selective inversion of output bits */
2180 fecOcRegIprInvert &= (~(InvertDataMask));
2181 if (state->m_invertDATA == true)
2182 fecOcRegIprInvert |= InvertDataMask;
2183 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2184 if (state->m_invertERR == true)
2185 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2186 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2187 if (state->m_invertSTR == true)
2188 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2189 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2190 if (state->m_invertVAL == true)
2191 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2192 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2193 if (state->m_invertCLK == true)
2194 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002195
2196 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002197}
2198
2199#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2200
2201static int SetAgcRf(struct drxk_state *state,
2202 struct SCfgAgc *pAgcCfg, bool isDTV)
2203{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002204 int status = -EINVAL;
2205 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002206 struct SCfgAgc *pIfAgcSettings;
2207
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002208 dprintk(1, "\n");
2209
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002210 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002211 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002212
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002213 switch (pAgcCfg->ctrlMode) {
2214 case DRXK_AGC_CTRL_AUTO:
2215 /* Enable RF AGC DAC */
2216 status = read16(state, IQM_AF_STDBY__A, &data);
2217 if (status < 0)
2218 goto error;
2219 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2220 status = write16(state, IQM_AF_STDBY__A, data);
2221 if (status < 0)
2222 goto error;
2223 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2224 if (status < 0)
2225 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002226
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002227 /* Enable SCU RF AGC loop */
2228 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002229
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002230 /* Polarity */
2231 if (state->m_RfAgcPol)
2232 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2233 else
2234 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2235 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2236 if (status < 0)
2237 goto error;
2238
2239 /* Set speed (using complementary reduction value) */
2240 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2241 if (status < 0)
2242 goto error;
2243
2244 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2245 data |= (~(pAgcCfg->speed <<
2246 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2247 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2248
2249 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2250 if (status < 0)
2251 goto error;
2252
2253 if (IsDVBT(state))
2254 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2255 else if (IsQAM(state))
2256 pIfAgcSettings = &state->m_qamIfAgcCfg;
2257 else
2258 pIfAgcSettings = &state->m_atvIfAgcCfg;
2259 if (pIfAgcSettings == NULL) {
2260 status = -EINVAL;
2261 goto error;
2262 }
2263
2264 /* Set TOP, only if IF-AGC is in AUTO mode */
2265 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2266 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002267 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002268 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002269
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002270 /* Cut-Off current */
2271 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2272 if (status < 0)
2273 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002274
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002275 /* Max. output level */
2276 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2277 if (status < 0)
2278 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002279
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002280 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002281
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002282 case DRXK_AGC_CTRL_USER:
2283 /* Enable RF AGC DAC */
2284 status = read16(state, IQM_AF_STDBY__A, &data);
2285 if (status < 0)
2286 goto error;
2287 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2288 status = write16(state, IQM_AF_STDBY__A, data);
2289 if (status < 0)
2290 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002291
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002292 /* Disable SCU RF AGC loop */
2293 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2294 if (status < 0)
2295 goto error;
2296 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2297 if (state->m_RfAgcPol)
2298 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2299 else
2300 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2301 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2302 if (status < 0)
2303 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002304
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002305 /* SCU c.o.c. to 0, enabling full control range */
2306 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2307 if (status < 0)
2308 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002309
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002310 /* Write value to output pin */
2311 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2312 if (status < 0)
2313 goto error;
2314 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002315
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002316 case DRXK_AGC_CTRL_OFF:
2317 /* Disable RF AGC DAC */
2318 status = read16(state, IQM_AF_STDBY__A, &data);
2319 if (status < 0)
2320 goto error;
2321 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2322 status = write16(state, IQM_AF_STDBY__A, data);
2323 if (status < 0)
2324 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002325
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002326 /* Disable SCU RF AGC loop */
2327 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2328 if (status < 0)
2329 goto error;
2330 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2331 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2332 if (status < 0)
2333 goto error;
2334 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002335
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002336 default:
2337 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002338
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002339 }
2340error:
2341 if (status < 0)
2342 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002343 return status;
2344}
2345
2346#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2347
Oliver Endrissebc7de22011-07-03 13:49:44 -03002348static int SetAgcIf(struct drxk_state *state,
2349 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002350{
2351 u16 data = 0;
2352 int status = 0;
2353 struct SCfgAgc *pRfAgcSettings;
2354
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002355 dprintk(1, "\n");
2356
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002357 switch (pAgcCfg->ctrlMode) {
2358 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002359
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002360 /* Enable IF AGC DAC */
2361 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002362 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002363 goto error;
2364 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2365 status = write16(state, IQM_AF_STDBY__A, data);
2366 if (status < 0)
2367 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002368
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002369 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2370 if (status < 0)
2371 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002372
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002373 /* Enable SCU IF AGC loop */
2374 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2375
2376 /* Polarity */
2377 if (state->m_IfAgcPol)
2378 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2379 else
2380 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2381 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2382 if (status < 0)
2383 goto error;
2384
2385 /* Set speed (using complementary reduction value) */
2386 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2387 if (status < 0)
2388 goto error;
2389 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2390 data |= (~(pAgcCfg->speed <<
2391 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2392 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2393
2394 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2395 if (status < 0)
2396 goto error;
2397
2398 if (IsQAM(state))
2399 pRfAgcSettings = &state->m_qamRfAgcCfg;
2400 else
2401 pRfAgcSettings = &state->m_atvRfAgcCfg;
2402 if (pRfAgcSettings == NULL)
2403 return -1;
2404 /* Restore TOP */
2405 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2406 if (status < 0)
2407 goto error;
2408 break;
2409
2410 case DRXK_AGC_CTRL_USER:
2411
2412 /* Enable IF AGC DAC */
2413 status = read16(state, IQM_AF_STDBY__A, &data);
2414 if (status < 0)
2415 goto error;
2416 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2417 status = write16(state, IQM_AF_STDBY__A, data);
2418 if (status < 0)
2419 goto error;
2420
2421 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2422 if (status < 0)
2423 goto error;
2424
2425 /* Disable SCU IF AGC loop */
2426 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2427
2428 /* Polarity */
2429 if (state->m_IfAgcPol)
2430 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2431 else
2432 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2433 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2434 if (status < 0)
2435 goto error;
2436
2437 /* Write value to output pin */
2438 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2439 if (status < 0)
2440 goto error;
2441 break;
2442
2443 case DRXK_AGC_CTRL_OFF:
2444
2445 /* Disable If AGC DAC */
2446 status = read16(state, IQM_AF_STDBY__A, &data);
2447 if (status < 0)
2448 goto error;
2449 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2450 status = write16(state, IQM_AF_STDBY__A, data);
2451 if (status < 0)
2452 goto error;
2453
2454 /* Disable SCU IF AGC loop */
2455 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2456 if (status < 0)
2457 goto error;
2458 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2459 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2460 if (status < 0)
2461 goto error;
2462 break;
2463 } /* switch (agcSettingsIf->ctrlMode) */
2464
2465 /* always set the top to support
2466 configurations without if-loop */
2467 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2468error:
2469 if (status < 0)
2470 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002471 return status;
2472}
2473
2474static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2475{
2476 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002477 int status;
2478 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002479
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002480 dprintk(1, "\n");
2481
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002482 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2483 if (status < 0) {
2484 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2485 return status;
2486 }
2487
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002488 *pValue = 0;
2489
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002490 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2491 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2492 if (Level < 14000)
2493 *pValue = (14000 - Level) / 4;
2494 else
2495 *pValue = 0;
2496
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002497 return status;
2498}
2499
Oliver Endrissebc7de22011-07-03 13:49:44 -03002500static int GetQAMSignalToNoise(struct drxk_state *state,
2501 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002502{
2503 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002504 u16 qamSlErrPower = 0; /* accum. error between
2505 raw and sliced symbols */
2506 u32 qamSlSigPower = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002507 QAM modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002508 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002509
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002510 dprintk(1, "\n");
2511
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002512 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002513
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002514 /* get the register value needed for MER */
2515 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2516 if (status < 0) {
2517 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2518 return -EINVAL;
2519 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002520
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002521 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002522 case QAM_16:
2523 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2524 break;
2525 case QAM_32:
2526 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2527 break;
2528 case QAM_64:
2529 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2530 break;
2531 case QAM_128:
2532 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2533 break;
2534 default:
2535 case QAM_256:
2536 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2537 break;
2538 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002539
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002540 if (qamSlErrPower > 0) {
2541 qamSlMer = Log10Times100(qamSlSigPower) -
2542 Log10Times100((u32) qamSlErrPower);
2543 }
2544 *pSignalToNoise = qamSlMer;
2545
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002546 return status;
2547}
2548
Oliver Endrissebc7de22011-07-03 13:49:44 -03002549static int GetDVBTSignalToNoise(struct drxk_state *state,
2550 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002551{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002552 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002553 u16 regData = 0;
2554 u32 EqRegTdSqrErrI = 0;
2555 u32 EqRegTdSqrErrQ = 0;
2556 u16 EqRegTdSqrErrExp = 0;
2557 u16 EqRegTdTpsPwrOfs = 0;
2558 u16 EqRegTdReqSmbCnt = 0;
2559 u32 tpsCnt = 0;
2560 u32 SqrErrIQ = 0;
2561 u32 a = 0;
2562 u32 b = 0;
2563 u32 c = 0;
2564 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002565 u16 transmissionParams = 0;
2566
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002567 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002568
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002569 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2570 if (status < 0)
2571 goto error;
2572 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2573 if (status < 0)
2574 goto error;
2575 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2576 if (status < 0)
2577 goto error;
2578 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2579 if (status < 0)
2580 goto error;
2581 /* Extend SQR_ERR_I operational range */
2582 EqRegTdSqrErrI = (u32) regData;
2583 if ((EqRegTdSqrErrExp > 11) &&
2584 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2585 EqRegTdSqrErrI += 0x00010000UL;
2586 }
2587 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2588 if (status < 0)
2589 goto error;
2590 /* Extend SQR_ERR_Q operational range */
2591 EqRegTdSqrErrQ = (u32) regData;
2592 if ((EqRegTdSqrErrExp > 11) &&
2593 (EqRegTdSqrErrQ < 0x00000FFFUL))
2594 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002595
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002596 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2597 if (status < 0)
2598 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002599
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002600 /* Check input data for MER */
2601
2602 /* MER calculation (in 0.1 dB) without math.h */
2603 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2604 iMER = 0;
2605 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2606 /* No error at all, this must be the HW reset value
2607 * Apparently no first measurement yet
2608 * Set MER to 0.0 */
2609 iMER = 0;
2610 } else {
2611 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2612 EqRegTdSqrErrExp;
2613 if ((transmissionParams &
2614 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2615 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2616 tpsCnt = 17;
2617 else
2618 tpsCnt = 68;
2619
2620 /* IMER = 100 * log10 (x)
2621 where x = (EqRegTdTpsPwrOfs^2 *
2622 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2623
2624 => IMER = a + b -c
2625 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2626 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2627 c = 100 * log10 (SqrErrIQ)
2628 */
2629
2630 /* log(x) x = 9bits * 9bits->18 bits */
2631 a = Log10Times100(EqRegTdTpsPwrOfs *
2632 EqRegTdTpsPwrOfs);
2633 /* log(x) x = 16bits * 7bits->23 bits */
2634 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2635 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2636 c = Log10Times100(SqrErrIQ);
2637
2638 iMER = a + b;
2639 /* No negative MER, clip to zero */
2640 if (iMER > c)
2641 iMER -= c;
2642 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002643 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002644 }
2645 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002646
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002647error:
2648 if (status < 0)
2649 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002650 return status;
2651}
2652
2653static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2654{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002655 dprintk(1, "\n");
2656
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002657 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002658 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002659 case OM_DVBT:
2660 return GetDVBTSignalToNoise(state, pSignalToNoise);
2661 case OM_QAM_ITU_A:
2662 case OM_QAM_ITU_C:
2663 return GetQAMSignalToNoise(state, pSignalToNoise);
2664 default:
2665 break;
2666 }
2667 return 0;
2668}
2669
2670#if 0
2671static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2672{
2673 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2674 int status = 0;
2675
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002676 dprintk(1, "\n");
2677
Oliver Endrissebc7de22011-07-03 13:49:44 -03002678 static s32 QE_SN[] = {
2679 51, /* QPSK 1/2 */
2680 69, /* QPSK 2/3 */
2681 79, /* QPSK 3/4 */
2682 89, /* QPSK 5/6 */
2683 97, /* QPSK 7/8 */
2684 108, /* 16-QAM 1/2 */
2685 131, /* 16-QAM 2/3 */
2686 146, /* 16-QAM 3/4 */
2687 156, /* 16-QAM 5/6 */
2688 160, /* 16-QAM 7/8 */
2689 165, /* 64-QAM 1/2 */
2690 187, /* 64-QAM 2/3 */
2691 202, /* 64-QAM 3/4 */
2692 216, /* 64-QAM 5/6 */
2693 225, /* 64-QAM 7/8 */
2694 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002695
2696 *pQuality = 0;
2697
2698 do {
2699 s32 SignalToNoise = 0;
2700 u16 Constellation = 0;
2701 u16 CodeRate = 0;
2702 u32 SignalToNoiseRel;
2703 u32 BERQuality;
2704
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002705 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2706 if (status < 0)
2707 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002708 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002709 if (status < 0)
2710 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002711 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2712
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002713 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002714 if (status < 0)
2715 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002716 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2717
2718 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2719 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2720 break;
2721 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002722 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002723 BERQuality = 100;
2724
Oliver Endrissebc7de22011-07-03 13:49:44 -03002725 if (SignalToNoiseRel < -70)
2726 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002727 else if (SignalToNoiseRel < 30)
2728 *pQuality = ((SignalToNoiseRel + 70) *
2729 BERQuality) / 100;
2730 else
2731 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002732 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002733 return 0;
2734};
2735
Oliver Endrissebc7de22011-07-03 13:49:44 -03002736static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002737{
2738 int status = 0;
2739 *pQuality = 0;
2740
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002741 dprintk(1, "\n");
2742
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002743 do {
2744 u32 SignalToNoise = 0;
2745 u32 BERQuality = 100;
2746 u32 SignalToNoiseRel = 0;
2747
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002748 status = GetQAMSignalToNoise(state, &SignalToNoise);
2749 if (status < 0)
2750 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002751
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002752 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002753 case QAM_16:
2754 SignalToNoiseRel = SignalToNoise - 200;
2755 break;
2756 case QAM_32:
2757 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002758 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002759 case QAM_64:
2760 SignalToNoiseRel = SignalToNoise - 260;
2761 break;
2762 case QAM_128:
2763 SignalToNoiseRel = SignalToNoise - 290;
2764 break;
2765 default:
2766 case QAM_256:
2767 SignalToNoiseRel = SignalToNoise - 320;
2768 break;
2769 }
2770
2771 if (SignalToNoiseRel < -70)
2772 *pQuality = 0;
2773 else if (SignalToNoiseRel < 30)
2774 *pQuality = ((SignalToNoiseRel + 70) *
2775 BERQuality) / 100;
2776 else
2777 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002778 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002779
2780 return status;
2781}
2782
2783static int GetQuality(struct drxk_state *state, s32 *pQuality)
2784{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002785 dprintk(1, "\n");
2786
Oliver Endrissebc7de22011-07-03 13:49:44 -03002787 switch (state->m_OperationMode) {
2788 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002789 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002790 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002791 return GetDVBCQuality(state, pQuality);
2792 default:
2793 break;
2794 }
2795
2796 return 0;
2797}
2798#endif
2799
2800/* Free data ram in SIO HI */
2801#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2802#define SIO_HI_RA_RAM_USR_END__A 0x420060
2803
2804#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2805#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2806#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2807#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2808
2809#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2810#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2811#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2812
2813static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2814{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002815 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002816
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002817 dprintk(1, "\n");
2818
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002819 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002820 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002821 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002822 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002823
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002824 if (state->no_i2c_bridge)
2825 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002826
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002827 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2828 if (status < 0)
2829 goto error;
2830 if (bEnableBridge) {
2831 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 -03002832 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002833 goto error;
2834 } else {
2835 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2836 if (status < 0)
2837 goto error;
2838 }
2839
2840 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2841
2842error:
2843 if (status < 0)
2844 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002845 return status;
2846}
2847
Oliver Endrissebc7de22011-07-03 13:49:44 -03002848static int SetPreSaw(struct drxk_state *state,
2849 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002850{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002851 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002852
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002853 dprintk(1, "\n");
2854
Oliver Endrissebc7de22011-07-03 13:49:44 -03002855 if ((pPreSawCfg == NULL)
2856 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002857 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002858
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002859 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002860error:
2861 if (status < 0)
2862 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002863 return status;
2864}
2865
2866static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002867 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002868{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002869 u16 blStatus = 0;
2870 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2871 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2872 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002873 unsigned long end;
2874
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002875 dprintk(1, "\n");
2876
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002877 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002878 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2879 if (status < 0)
2880 goto error;
2881 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2882 if (status < 0)
2883 goto error;
2884 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2885 if (status < 0)
2886 goto error;
2887 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2888 if (status < 0)
2889 goto error;
2890 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2891 if (status < 0)
2892 goto error;
2893 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2894 if (status < 0)
2895 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002896
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002897 end = jiffies + msecs_to_jiffies(timeOut);
2898 do {
2899 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2900 if (status < 0)
2901 goto error;
2902 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2903 if (blStatus == 0x1) {
2904 printk(KERN_ERR "drxk: SIO not ready\n");
2905 status = -EINVAL;
2906 goto error2;
2907 }
2908error:
2909 if (status < 0)
2910 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2911error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002912 mutex_unlock(&state->mutex);
2913 return status;
2914
2915}
2916
Oliver Endrissebc7de22011-07-03 13:49:44 -03002917static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002918{
2919 u16 data = 0;
2920 int status;
2921
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002922 dprintk(1, "\n");
2923
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002924 /* Start measurement */
2925 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2926 if (status < 0)
2927 goto error;
2928 status = write16(state, IQM_AF_START_LOCK__A, 1);
2929 if (status < 0)
2930 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002931
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002932 *count = 0;
2933 status = read16(state, IQM_AF_PHASE0__A, &data);
2934 if (status < 0)
2935 goto error;
2936 if (data == 127)
2937 *count = *count + 1;
2938 status = read16(state, IQM_AF_PHASE1__A, &data);
2939 if (status < 0)
2940 goto error;
2941 if (data == 127)
2942 *count = *count + 1;
2943 status = read16(state, IQM_AF_PHASE2__A, &data);
2944 if (status < 0)
2945 goto error;
2946 if (data == 127)
2947 *count = *count + 1;
2948
2949error:
2950 if (status < 0)
2951 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002952 return status;
2953}
2954
2955static int ADCSynchronization(struct drxk_state *state)
2956{
2957 u16 count = 0;
2958 int status;
2959
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002960 dprintk(1, "\n");
2961
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002962 status = ADCSyncMeasurement(state, &count);
2963 if (status < 0)
2964 goto error;
2965
2966 if (count == 1) {
2967 /* Try sampling on a diffrent edge */
2968 u16 clkNeg = 0;
2969
2970 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2971 if (status < 0)
2972 goto error;
2973 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2974 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2975 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2976 clkNeg |=
2977 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2978 } else {
2979 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2980 clkNeg |=
2981 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2982 }
2983 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2984 if (status < 0)
2985 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002986 status = ADCSyncMeasurement(state, &count);
2987 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002988 goto error;
2989 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002990
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002991 if (count < 2)
2992 status = -EINVAL;
2993error:
2994 if (status < 0)
2995 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002996 return status;
2997}
2998
2999static int SetFrequencyShifter(struct drxk_state *state,
3000 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003001 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003002{
3003 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003004 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003005 u32 fmFrequencyShift = 0;
3006 bool tunerMirror = !state->m_bMirrorFreqSpect;
3007 u32 adcFreq;
3008 bool adcFlip;
3009 int status;
3010 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003011 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003012 u32 frequencyShift;
3013 bool imageToSelect;
3014
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003015 dprintk(1, "\n");
3016
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003017 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003018 Program frequency shifter
3019 No need to account for mirroring on RF
3020 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003021 if (isDTV) {
3022 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3023 (state->m_OperationMode == OM_QAM_ITU_C) ||
3024 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003025 selectPosImage = true;
3026 else
3027 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003028 }
3029 if (tunerMirror)
3030 /* tuner doesn't mirror */
3031 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003032 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003033 else
3034 /* tuner mirrors */
3035 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003036 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003037 if (ifFreqActual > samplingFrequency / 2) {
3038 /* adc mirrors */
3039 adcFreq = samplingFrequency - ifFreqActual;
3040 adcFlip = true;
3041 } else {
3042 /* adc doesn't mirror */
3043 adcFreq = ifFreqActual;
3044 adcFlip = false;
3045 }
3046
3047 frequencyShift = adcFreq;
3048 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003049 adcFlip ^ selectPosImage;
3050 state->m_IqmFsRateOfs =
3051 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003052
3053 if (imageToSelect)
3054 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3055
3056 /* Program frequency shifter with tuner offset compensation */
3057 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003058 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3059 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003060 if (status < 0)
3061 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003062 return status;
3063}
3064
3065static int InitAGC(struct drxk_state *state, bool isDTV)
3066{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003067 u16 ingainTgt = 0;
3068 u16 ingainTgtMin = 0;
3069 u16 ingainTgtMax = 0;
3070 u16 clpCyclen = 0;
3071 u16 clpSumMin = 0;
3072 u16 clpDirTo = 0;
3073 u16 snsSumMin = 0;
3074 u16 snsSumMax = 0;
3075 u16 clpSumMax = 0;
3076 u16 snsDirTo = 0;
3077 u16 kiInnergainMin = 0;
3078 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003079 u16 ifIaccuHiTgtMin = 0;
3080 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003081 u16 data = 0;
3082 u16 fastClpCtrlDelay = 0;
3083 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003084 int status = 0;
3085
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003086 dprintk(1, "\n");
3087
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003088 /* Common settings */
3089 snsSumMax = 1023;
3090 ifIaccuHiTgtMin = 2047;
3091 clpCyclen = 500;
3092 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003093
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003094 /* AGCInit() not available for DVBT; init done in microcode */
3095 if (!IsQAM(state)) {
3096 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3097 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003098 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003099
3100 /* FIXME: Analog TV AGC require different settings */
3101
3102 /* Standard specific settings */
3103 clpSumMin = 8;
3104 clpDirTo = (u16) -9;
3105 clpCtrlMode = 0;
3106 snsSumMin = 8;
3107 snsDirTo = (u16) -9;
3108 kiInnergainMin = (u16) -1030;
3109 ifIaccuHiTgtMax = 0x2380;
3110 ifIaccuHiTgt = 0x2380;
3111 ingainTgtMin = 0x0511;
3112 ingainTgt = 0x0511;
3113 ingainTgtMax = 5119;
3114 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3115
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003116 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3117 if (status < 0)
3118 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003119
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003120 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3121 if (status < 0)
3122 goto error;
3123 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3124 if (status < 0)
3125 goto error;
3126 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3127 if (status < 0)
3128 goto error;
3129 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3130 if (status < 0)
3131 goto error;
3132 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3133 if (status < 0)
3134 goto error;
3135 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3136 if (status < 0)
3137 goto error;
3138 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3139 if (status < 0)
3140 goto error;
3141 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3142 if (status < 0)
3143 goto error;
3144 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3145 if (status < 0)
3146 goto error;
3147 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3148 if (status < 0)
3149 goto error;
3150 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3151 if (status < 0)
3152 goto error;
3153 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3154 if (status < 0)
3155 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003156
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003157 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3158 if (status < 0)
3159 goto error;
3160 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3161 if (status < 0)
3162 goto error;
3163 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3164 if (status < 0)
3165 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003166
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003167 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3168 if (status < 0)
3169 goto error;
3170 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3171 if (status < 0)
3172 goto error;
3173 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3174 if (status < 0)
3175 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003176
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003177 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3178 if (status < 0)
3179 goto error;
3180 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3181 if (status < 0)
3182 goto error;
3183 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3184 if (status < 0)
3185 goto error;
3186 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3187 if (status < 0)
3188 goto error;
3189 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3190 if (status < 0)
3191 goto error;
3192 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3193 if (status < 0)
3194 goto error;
3195 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3196 if (status < 0)
3197 goto error;
3198 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3199 if (status < 0)
3200 goto error;
3201 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3202 if (status < 0)
3203 goto error;
3204 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3205 if (status < 0)
3206 goto error;
3207 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3208 if (status < 0)
3209 goto error;
3210 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3211 if (status < 0)
3212 goto error;
3213 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3214 if (status < 0)
3215 goto error;
3216 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3217 if (status < 0)
3218 goto error;
3219 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3220 if (status < 0)
3221 goto error;
3222 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3223 if (status < 0)
3224 goto error;
3225 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3226 if (status < 0)
3227 goto error;
3228 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3229 if (status < 0)
3230 goto error;
3231 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3232 if (status < 0)
3233 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003234
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003235 /* Initialize inner-loop KI gain factors */
3236 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3237 if (status < 0)
3238 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003239
3240 data = 0x0657;
3241 data &= ~SCU_RAM_AGC_KI_RF__M;
3242 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3243 data &= ~SCU_RAM_AGC_KI_IF__M;
3244 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3245
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003246 status = write16(state, SCU_RAM_AGC_KI__A, data);
3247error:
3248 if (status < 0)
3249 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003250 return status;
3251}
3252
Oliver Endrissebc7de22011-07-03 13:49:44 -03003253static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003254{
3255 int status;
3256
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003257 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003258 if (packetErr == NULL)
3259 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3260 else
3261 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3262 if (status < 0)
3263 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003264 return status;
3265}
3266
3267static int DVBTScCommand(struct drxk_state *state,
3268 u16 cmd, u16 subcmd,
3269 u16 param0, u16 param1, u16 param2,
3270 u16 param3, u16 param4)
3271{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003272 u16 curCmd = 0;
3273 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003274 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003275 u16 scExec = 0;
3276 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003277
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003278 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003279 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003280 if (scExec != 1) {
3281 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003282 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003283 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003284 if (status < 0)
3285 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003286
3287 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003288 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003289 do {
3290 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003291 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003292 retryCnt++;
3293 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003294 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3295 goto error;
3296
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003297 /* Write sub-command */
3298 switch (cmd) {
3299 /* All commands using sub-cmd */
3300 case OFDM_SC_RA_RAM_CMD_PROC_START:
3301 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3302 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003303 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3304 if (status < 0)
3305 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003306 break;
3307 default:
3308 /* Do nothing */
3309 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003310 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003311
3312 /* Write needed parameters and the command */
3313 switch (cmd) {
3314 /* All commands using 5 parameters */
3315 /* All commands using 4 parameters */
3316 /* All commands using 3 parameters */
3317 /* All commands using 2 parameters */
3318 case OFDM_SC_RA_RAM_CMD_PROC_START:
3319 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3320 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003321 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003322 /* All commands using 1 parameters */
3323 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3324 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003325 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003326 /* All commands using 0 parameters */
3327 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3328 case OFDM_SC_RA_RAM_CMD_NULL:
3329 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003330 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003331 break;
3332 default:
3333 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003334 status = -EINVAL;
3335 }
3336 if (status < 0)
3337 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003338
3339 /* Wait until sc is ready processing command */
3340 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003341 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003342 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003343 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003344 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003345 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003346 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3347 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003348
3349 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003350 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003351 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003352 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003353 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003354 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003355 if (status < 0)
3356 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003357
3358 /* Retreive results parameters from SC */
3359 switch (cmd) {
3360 /* All commands yielding 5 results */
3361 /* All commands yielding 4 results */
3362 /* All commands yielding 3 results */
3363 /* All commands yielding 2 results */
3364 /* All commands yielding 1 result */
3365 case OFDM_SC_RA_RAM_CMD_USER_IO:
3366 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003367 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003368 /* All commands yielding 0 results */
3369 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3370 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3371 case OFDM_SC_RA_RAM_CMD_PROC_START:
3372 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3373 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3374 case OFDM_SC_RA_RAM_CMD_NULL:
3375 break;
3376 default:
3377 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003378 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003379 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003380 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003381error:
3382 if (status < 0)
3383 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003384 return status;
3385}
3386
Oliver Endrissebc7de22011-07-03 13:49:44 -03003387static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003388{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003389 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003390 int status;
3391
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003392 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003393 status = CtrlPowerMode(state, &powerMode);
3394 if (status < 0)
3395 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003396 return status;
3397}
3398
Oliver Endrissebc7de22011-07-03 13:49:44 -03003399static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003400{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003401 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003402
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003403 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003404 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003405 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003406 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003407 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003408 if (status < 0)
3409 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003410 return status;
3411}
3412
3413#define DEFAULT_FR_THRES_8K 4000
3414static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3415{
3416
3417 int status;
3418
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003419 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003420 if (*enabled == true) {
3421 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003422 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003423 DEFAULT_FR_THRES_8K);
3424 } else {
3425 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003426 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003427 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003428 if (status < 0)
3429 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003430
3431 return status;
3432}
3433
3434static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3435 struct DRXKCfgDvbtEchoThres_t *echoThres)
3436{
3437 u16 data = 0;
3438 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003439
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003440 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003441 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3442 if (status < 0)
3443 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003444
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003445 switch (echoThres->fftMode) {
3446 case DRX_FFTMODE_2K:
3447 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3448 data |= ((echoThres->threshold <<
3449 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3450 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003451 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003452 case DRX_FFTMODE_8K:
3453 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3454 data |= ((echoThres->threshold <<
3455 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3456 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003457 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003458 default:
3459 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003460 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003461
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003462 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3463error:
3464 if (status < 0)
3465 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003466 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003467}
3468
3469static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003470 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003471{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003472 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003473
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003474 dprintk(1, "\n");
3475
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003476 switch (*speed) {
3477 case DRXK_DVBT_SQI_SPEED_FAST:
3478 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3479 case DRXK_DVBT_SQI_SPEED_SLOW:
3480 break;
3481 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003482 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003483 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003484 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003485 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003486error:
3487 if (status < 0)
3488 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003489 return status;
3490}
3491
3492/*============================================================================*/
3493
3494/**
3495* \brief Activate DVBT specific presets
3496* \param demod instance of demodulator.
3497* \return DRXStatus_t.
3498*
3499* Called in DVBTSetStandard
3500*
3501*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003502static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003503{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003504 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003505 bool setincenable = false;
3506 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003507
Oliver Endrissebc7de22011-07-03 13:49:44 -03003508 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3509 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003510
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003511 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003512 status = DVBTCtrlSetIncEnable(state, &setincenable);
3513 if (status < 0)
3514 goto error;
3515 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3516 if (status < 0)
3517 goto error;
3518 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3519 if (status < 0)
3520 goto error;
3521 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3522 if (status < 0)
3523 goto error;
3524 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3525error:
3526 if (status < 0)
3527 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003528 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003529}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003530
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003531/*============================================================================*/
3532
3533/**
3534* \brief Initialize channelswitch-independent settings for DVBT.
3535* \param demod instance of demodulator.
3536* \return DRXStatus_t.
3537*
3538* For ROM code channel filter taps are loaded from the bootloader. For microcode
3539* the DVB-T taps from the drxk_filters.h are used.
3540*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003541static int SetDVBTStandard(struct drxk_state *state,
3542 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003543{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003544 u16 cmdResult = 0;
3545 u16 data = 0;
3546 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003547
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003548 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003549
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003550 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003551 /* added antenna switch */
3552 SwitchAntennaToDVBT(state);
3553 /* send OFDM reset command */
3554 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 -03003555 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003556 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003557
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003558 /* send OFDM setenv command */
3559 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3560 if (status < 0)
3561 goto error;
3562
3563 /* reset datapath for OFDM, processors first */
3564 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3565 if (status < 0)
3566 goto error;
3567 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3568 if (status < 0)
3569 goto error;
3570 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3571 if (status < 0)
3572 goto error;
3573
3574 /* IQM setup */
3575 /* synchronize on ofdstate->m_festart */
3576 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3577 if (status < 0)
3578 goto error;
3579 /* window size for clipping ADC detection */
3580 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3581 if (status < 0)
3582 goto error;
3583 /* window size for for sense pre-SAW detection */
3584 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3585 if (status < 0)
3586 goto error;
3587 /* sense threshold for sense pre-SAW detection */
3588 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3589 if (status < 0)
3590 goto error;
3591 status = SetIqmAf(state, true);
3592 if (status < 0)
3593 goto error;
3594
3595 status = write16(state, IQM_AF_AGC_RF__A, 0);
3596 if (status < 0)
3597 goto error;
3598
3599 /* Impulse noise cruncher setup */
3600 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3601 if (status < 0)
3602 goto error;
3603 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3604 if (status < 0)
3605 goto error;
3606 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3607 if (status < 0)
3608 goto error;
3609
3610 status = write16(state, IQM_RC_STRETCH__A, 16);
3611 if (status < 0)
3612 goto error;
3613 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3614 if (status < 0)
3615 goto error;
3616 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3617 if (status < 0)
3618 goto error;
3619 status = write16(state, IQM_CF_SCALE__A, 1600);
3620 if (status < 0)
3621 goto error;
3622 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3623 if (status < 0)
3624 goto error;
3625
3626 /* virtual clipping threshold for clipping ADC detection */
3627 status = write16(state, IQM_AF_CLP_TH__A, 448);
3628 if (status < 0)
3629 goto error;
3630 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3631 if (status < 0)
3632 goto error;
3633
3634 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3635 if (status < 0)
3636 goto error;
3637
3638 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3639 if (status < 0)
3640 goto error;
3641 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3642 if (status < 0)
3643 goto error;
3644 /* enable power measurement interrupt */
3645 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3646 if (status < 0)
3647 goto error;
3648 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3649 if (status < 0)
3650 goto error;
3651
3652 /* IQM will not be reset from here, sync ADC and update/init AGC */
3653 status = ADCSynchronization(state);
3654 if (status < 0)
3655 goto error;
3656 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3657 if (status < 0)
3658 goto error;
3659
3660 /* Halt SCU to enable safe non-atomic accesses */
3661 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3662 if (status < 0)
3663 goto error;
3664
3665 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3666 if (status < 0)
3667 goto error;
3668 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3669 if (status < 0)
3670 goto error;
3671
3672 /* Set Noise Estimation notch width and enable DC fix */
3673 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3674 if (status < 0)
3675 goto error;
3676 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3677 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3678 if (status < 0)
3679 goto error;
3680
3681 /* Activate SCU to enable SCU commands */
3682 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3683 if (status < 0)
3684 goto error;
3685
3686 if (!state->m_DRXK_A3_ROM_CODE) {
3687 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3688 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3689 if (status < 0)
3690 goto error;
3691 }
3692
3693 /* OFDM_SC setup */
3694#ifdef COMPILE_FOR_NONRT
3695 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3696 if (status < 0)
3697 goto error;
3698 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3699 if (status < 0)
3700 goto error;
3701#endif
3702
3703 /* FEC setup */
3704 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3705 if (status < 0)
3706 goto error;
3707
3708
3709#ifdef COMPILE_FOR_NONRT
3710 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3711 if (status < 0)
3712 goto error;
3713#else
3714 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3715 if (status < 0)
3716 goto error;
3717#endif
3718 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3719 if (status < 0)
3720 goto error;
3721
3722 /* Setup MPEG bus */
3723 status = MPEGTSDtoSetup(state, OM_DVBT);
3724 if (status < 0)
3725 goto error;
3726 /* Set DVBT Presets */
3727 status = DVBTActivatePresets(state);
3728 if (status < 0)
3729 goto error;
3730
3731error:
3732 if (status < 0)
3733 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003734 return status;
3735}
3736
3737/*============================================================================*/
3738/**
3739* \brief Start dvbt demodulating for channel.
3740* \param demod instance of demodulator.
3741* \return DRXStatus_t.
3742*/
3743static int DVBTStart(struct drxk_state *state)
3744{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003745 u16 param1;
3746 int status;
3747 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003748
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003749 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003750 /* Start correct processes to get in lock */
3751 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003752 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3753 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3754 if (status < 0)
3755 goto error;
3756 /* Start FEC OC */
3757 status = MPEGTSStart(state);
3758 if (status < 0)
3759 goto error;
3760 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3761 if (status < 0)
3762 goto error;
3763error:
3764 if (status < 0)
3765 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003766 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003767}
3768
3769
3770/*============================================================================*/
3771
3772/**
3773* \brief Set up dvbt demodulator for channel.
3774* \param demod instance of demodulator.
3775* \return DRXStatus_t.
3776* // original DVBTSetChannel()
3777*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003778static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3779 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003780{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003781 u16 cmdResult = 0;
3782 u16 transmissionParams = 0;
3783 u16 operationMode = 0;
3784 u32 iqmRcRateOfs = 0;
3785 u32 bandwidth = 0;
3786 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003787 int status;
3788
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003789 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003790
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003791 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3792 if (status < 0)
3793 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003794
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003795 /* Halt SCU to enable safe non-atomic accesses */
3796 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3797 if (status < 0)
3798 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003799
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003800 /* Stop processors */
3801 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3802 if (status < 0)
3803 goto error;
3804 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3805 if (status < 0)
3806 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003807
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003808 /* Mandatory fix, always stop CP, required to set spl offset back to
3809 hardware default (is set to 0 by ucode during pilot detection */
3810 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3811 if (status < 0)
3812 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003813
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003814 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003815
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003816 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003817 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003818 case TRANSMISSION_MODE_AUTO:
3819 default:
3820 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3821 /* fall through , try first guess DRX_FFTMODE_8K */
3822 case TRANSMISSION_MODE_8K:
3823 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003824 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003825 case TRANSMISSION_MODE_2K:
3826 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003827 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003828 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003829
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003830 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003831 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003832 default:
3833 case GUARD_INTERVAL_AUTO:
3834 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3835 /* fall through , try first guess DRX_GUARD_1DIV4 */
3836 case GUARD_INTERVAL_1_4:
3837 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003838 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003839 case GUARD_INTERVAL_1_32:
3840 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003841 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003842 case GUARD_INTERVAL_1_16:
3843 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003844 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003845 case GUARD_INTERVAL_1_8:
3846 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003847 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003848 }
3849
3850 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003851 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003852 case HIERARCHY_AUTO:
3853 case HIERARCHY_NONE:
3854 default:
3855 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3856 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3857 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3858 /* break; */
3859 case HIERARCHY_1:
3860 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3861 break;
3862 case HIERARCHY_2:
3863 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3864 break;
3865 case HIERARCHY_4:
3866 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3867 break;
3868 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003869
3870
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003871 /* modulation */
3872 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003873 case QAM_AUTO:
3874 default:
3875 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3876 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3877 case QAM_64:
3878 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3879 break;
3880 case QPSK:
3881 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3882 break;
3883 case QAM_16:
3884 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3885 break;
3886 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003887#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003888 /* No hierachical channels support in BDA */
3889 /* Priority (only for hierarchical channels) */
3890 switch (channel->priority) {
3891 case DRX_PRIORITY_LOW:
3892 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3893 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3894 OFDM_EC_SB_PRIOR_LO);
3895 break;
3896 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003897 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003898 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3899 OFDM_EC_SB_PRIOR_HI));
3900 break;
3901 case DRX_PRIORITY_UNKNOWN: /* fall through */
3902 default:
3903 status = -EINVAL;
3904 goto error;
3905 }
3906#else
3907 /* Set Priorty high */
3908 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3909 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3910 if (status < 0)
3911 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003912#endif
3913
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003914 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003915 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003916 case FEC_AUTO:
3917 default:
3918 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3919 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3920 case FEC_2_3:
3921 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3922 break;
3923 case FEC_1_2:
3924 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3925 break;
3926 case FEC_3_4:
3927 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3928 break;
3929 case FEC_5_6:
3930 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3931 break;
3932 case FEC_7_8:
3933 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3934 break;
3935 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003936
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003937 /* SAW filter selection: normaly not necesarry, but if wanted
3938 the application can select a SAW filter via the driver by using UIOs */
3939 /* First determine real bandwidth (Hz) */
3940 /* Also set delay for impulse noise cruncher */
3941 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3942 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3943 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003944 switch (state->props.bandwidth_hz) {
3945 case 0:
3946 state->props.bandwidth_hz = 8000000;
3947 /* fall though */
3948 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003949 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;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003967 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003968 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;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003986 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003987 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.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004193* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004194* \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,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004202 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004203 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] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004216 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004217 SyncLoss (== 1) *
4218 ViterbiLoss (==1)
4219 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004220 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004221 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;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005287 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5288 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005289 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005290 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005291 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005292 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005293 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 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005301 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005302 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 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005317 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005318 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;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005388 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5389 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005390
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005391 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005392 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005393 * STEP 1: reset demodulator
5394 * resets FEC DI and FEC RS
5395 * resets QAM block
5396 * resets SCU variables
5397 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005398 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005399 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005400 goto error;
5401 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5402 if (status < 0)
5403 goto error;
5404 status = QAMResetQAM(state);
5405 if (status < 0)
5406 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005407
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005408 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005409 * STEP 2: configure demodulator
5410 * -set params; resets IQM,QAM,FEC HW; initializes some
5411 * SCU variables
5412 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005413 status = QAMSetSymbolrate(state);
5414 if (status < 0)
5415 goto error;
5416
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005417 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005418 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005419 case QAM_256:
5420 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5421 break;
5422 case QAM_AUTO:
5423 case QAM_64:
5424 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5425 break;
5426 case QAM_16:
5427 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5428 break;
5429 case QAM_32:
5430 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5431 break;
5432 case QAM_128:
5433 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5434 break;
5435 default:
5436 status = -EINVAL;
5437 break;
5438 }
5439 if (status < 0)
5440 goto error;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005441 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005442 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005443 if (state->m_OperationMode == OM_QAM_ITU_C)
5444 setParamParameters[2] = QAM_TOP_ANNEX_C;
5445 else
5446 setParamParameters[2] = QAM_TOP_ANNEX_A;
5447 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5448 /* Env parameters */
5449 /* check for LOCKRANGE Extented */
5450 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005451
5452 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 -03005453 if (status < 0) {
5454 /* Fall-back to the simpler call */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005455 if (state->m_OperationMode == OM_QAM_ITU_C)
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005456 setParamParameters[0] = QAM_TOP_ANNEX_C;
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005457 else
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005458 setParamParameters[0] = QAM_TOP_ANNEX_A;
5459 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult);
5460 if (status < 0)
5461 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005462
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005463 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005464 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005465 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
5466 }
5467 if (status < 0)
5468 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005469
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005470 /*
5471 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005472 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005473 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005474#if 0
5475 status = SetFrequency(channel, tunerFreqOffset));
5476 if (status < 0)
5477 goto error;
5478#endif
5479 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5480 if (status < 0)
5481 goto error;
5482
5483 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005484 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005485 if (status < 0)
5486 goto error;
5487
5488 /* Reset default values */
5489 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5490 if (status < 0)
5491 goto error;
5492 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5493 if (status < 0)
5494 goto error;
5495
5496 /* Reset default LC values */
5497 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5498 if (status < 0)
5499 goto error;
5500 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5501 if (status < 0)
5502 goto error;
5503 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5504 if (status < 0)
5505 goto error;
5506 status = write16(state, QAM_LC_MODE__A, 7);
5507 if (status < 0)
5508 goto error;
5509
5510 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5511 if (status < 0)
5512 goto error;
5513 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5514 if (status < 0)
5515 goto error;
5516 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5517 if (status < 0)
5518 goto error;
5519 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5520 if (status < 0)
5521 goto error;
5522 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5523 if (status < 0)
5524 goto error;
5525 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5526 if (status < 0)
5527 goto error;
5528 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5529 if (status < 0)
5530 goto error;
5531 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5532 if (status < 0)
5533 goto error;
5534 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5535 if (status < 0)
5536 goto error;
5537 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5538 if (status < 0)
5539 goto error;
5540 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5541 if (status < 0)
5542 goto error;
5543 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5544 if (status < 0)
5545 goto error;
5546 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5547 if (status < 0)
5548 goto error;
5549 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5550 if (status < 0)
5551 goto error;
5552 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5553 if (status < 0)
5554 goto error;
5555
5556 /* Mirroring, QAM-block starting point not inverted */
5557 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5558 if (status < 0)
5559 goto error;
5560
5561 /* Halt SCU to enable safe non-atomic accesses */
5562 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5563 if (status < 0)
5564 goto error;
5565
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005566 /* STEP 4: modulation specific setup */
5567 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005568 case QAM_16:
5569 status = SetQAM16(state);
5570 break;
5571 case QAM_32:
5572 status = SetQAM32(state);
5573 break;
5574 case QAM_AUTO:
5575 case QAM_64:
5576 status = SetQAM64(state);
5577 break;
5578 case QAM_128:
5579 status = SetQAM128(state);
5580 break;
5581 case QAM_256:
5582 status = SetQAM256(state);
5583 break;
5584 default:
5585 status = -EINVAL;
5586 break;
5587 }
5588 if (status < 0)
5589 goto error;
5590
5591 /* Activate SCU to enable SCU commands */
5592 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5593 if (status < 0)
5594 goto error;
5595
5596 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005597 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005598 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5599 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5600 if (status < 0)
5601 goto error;
5602
5603 /* Start processes */
5604 status = MPEGTSStart(state);
5605 if (status < 0)
5606 goto error;
5607 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5608 if (status < 0)
5609 goto error;
5610 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5611 if (status < 0)
5612 goto error;
5613 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5614 if (status < 0)
5615 goto error;
5616
5617 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5618 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5619 if (status < 0)
5620 goto error;
5621
5622 /* update global DRXK data container */
5623/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5624
5625error:
5626 if (status < 0)
5627 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005628 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005629}
5630
Oliver Endrissebc7de22011-07-03 13:49:44 -03005631static int SetQAMStandard(struct drxk_state *state,
5632 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005633{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005634 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005635#ifdef DRXK_QAM_TAPS
5636#define DRXK_QAMA_TAPS_SELECT
5637#include "drxk_filters.h"
5638#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005639#endif
5640
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005641 dprintk(1, "\n");
5642
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005643 /* added antenna switch */
5644 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005645
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005646 /* Ensure correct power-up mode */
5647 status = PowerUpQAM(state);
5648 if (status < 0)
5649 goto error;
5650 /* Reset QAM block */
5651 status = QAMResetQAM(state);
5652 if (status < 0)
5653 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005654
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005655 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005656
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005657 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5658 if (status < 0)
5659 goto error;
5660 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5661 if (status < 0)
5662 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005663
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005664 /* Upload IQM Channel Filter settings by
5665 boot loader from ROM table */
5666 switch (oMode) {
5667 case OM_QAM_ITU_A:
5668 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5669 break;
5670 case OM_QAM_ITU_C:
5671 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 -03005672 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005673 goto error;
5674 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5675 break;
5676 default:
5677 status = -EINVAL;
5678 }
5679 if (status < 0)
5680 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005681
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005682 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5683 if (status < 0)
5684 goto error;
5685 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5686 if (status < 0)
5687 goto error;
5688 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5689 if (status < 0)
5690 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005691
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005692 status = write16(state, IQM_RC_STRETCH__A, 21);
5693 if (status < 0)
5694 goto error;
5695 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5696 if (status < 0)
5697 goto error;
5698 status = write16(state, IQM_AF_CLP_TH__A, 448);
5699 if (status < 0)
5700 goto error;
5701 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5702 if (status < 0)
5703 goto error;
5704 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5705 if (status < 0)
5706 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005707
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005708 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5709 if (status < 0)
5710 goto error;
5711 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5712 if (status < 0)
5713 goto error;
5714 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5715 if (status < 0)
5716 goto error;
5717 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5718 if (status < 0)
5719 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005720
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005721 /* IQM Impulse Noise Processing Unit */
5722 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5723 if (status < 0)
5724 goto error;
5725 status = write16(state, IQM_CF_DATATH__A, 1000);
5726 if (status < 0)
5727 goto error;
5728 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5729 if (status < 0)
5730 goto error;
5731 status = write16(state, IQM_CF_DET_LCT__A, 0);
5732 if (status < 0)
5733 goto error;
5734 status = write16(state, IQM_CF_WND_LEN__A, 1);
5735 if (status < 0)
5736 goto error;
5737 status = write16(state, IQM_CF_PKDTH__A, 1);
5738 if (status < 0)
5739 goto error;
5740 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5741 if (status < 0)
5742 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005743
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005744 /* turn on IQMAF. Must be done before setAgc**() */
5745 status = SetIqmAf(state, true);
5746 if (status < 0)
5747 goto error;
5748 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5749 if (status < 0)
5750 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005751
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005752 /* IQM will not be reset from here, sync ADC and update/init AGC */
5753 status = ADCSynchronization(state);
5754 if (status < 0)
5755 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005756
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005757 /* Set the FSM step period */
5758 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5759 if (status < 0)
5760 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005761
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005762 /* Halt SCU to enable safe non-atomic accesses */
5763 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5764 if (status < 0)
5765 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005766
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005767 /* No more resets of the IQM, current standard correctly set =>
5768 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005769
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005770 status = InitAGC(state, true);
5771 if (status < 0)
5772 goto error;
5773 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5774 if (status < 0)
5775 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005776
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005777 /* Configure AGC's */
5778 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5779 if (status < 0)
5780 goto error;
5781 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5782 if (status < 0)
5783 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005784
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005785 /* Activate SCU to enable SCU commands */
5786 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5787error:
5788 if (status < 0)
5789 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005790 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005791}
5792
5793static int WriteGPIO(struct drxk_state *state)
5794{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005795 int status;
5796 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005797
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005798 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005799 /* stop lock indicator process */
5800 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5801 if (status < 0)
5802 goto error;
5803
5804 /* Write magic word to enable pdr reg write */
5805 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5806 if (status < 0)
5807 goto error;
5808
5809 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005810 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5811 /* write to io pad configuration register - output mode */
5812 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5813 if (status < 0)
5814 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005815
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005816 /* use corresponding bit in io data output registar */
5817 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5818 if (status < 0)
5819 goto error;
5820 if ((state->m_GPIO & 0x0001) == 0)
5821 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5822 else
5823 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5824 /* write back to io data output register */
5825 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5826 if (status < 0)
5827 goto error;
5828 }
5829 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5830 /* write to io pad configuration register - output mode */
5831 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5832 if (status < 0)
5833 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005834
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005835 /* use corresponding bit in io data output registar */
5836 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5837 if (status < 0)
5838 goto error;
5839 if ((state->m_GPIO & 0x0002) == 0)
5840 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5841 else
5842 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5843 /* write back to io data output register */
5844 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5845 if (status < 0)
5846 goto error;
5847 }
5848 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5849 /* write to io pad configuration register - output mode */
5850 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5851 if (status < 0)
5852 goto error;
5853
5854 /* use corresponding bit in io data output registar */
5855 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5856 if (status < 0)
5857 goto error;
5858 if ((state->m_GPIO & 0x0004) == 0)
5859 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5860 else
5861 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5862 /* write back to io data output register */
5863 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5864 if (status < 0)
5865 goto error;
5866 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005867 }
5868 /* Write magic word to disable pdr reg write */
5869 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5870error:
5871 if (status < 0)
5872 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005873 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005874}
5875
5876static int SwitchAntennaToQAM(struct drxk_state *state)
5877{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005878 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005879 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005880
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005881 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005882
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005883 if (!state->antenna_gpio)
5884 return 0;
5885
5886 gpio_state = state->m_GPIO & state->antenna_gpio;
5887
5888 if (state->antenna_dvbt ^ gpio_state) {
5889 /* Antenna is on DVB-T mode. Switch */
5890 if (state->antenna_dvbt)
5891 state->m_GPIO &= ~state->antenna_gpio;
5892 else
5893 state->m_GPIO |= state->antenna_gpio;
5894 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005895 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005896 if (status < 0)
5897 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005898 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005899}
5900
5901static int SwitchAntennaToDVBT(struct drxk_state *state)
5902{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005903 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005904 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005905
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005906 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005907
5908 if (!state->antenna_gpio)
5909 return 0;
5910
5911 gpio_state = state->m_GPIO & state->antenna_gpio;
5912
5913 if (!(state->antenna_dvbt ^ gpio_state)) {
5914 /* Antenna is on DVB-C mode. Switch */
5915 if (state->antenna_dvbt)
5916 state->m_GPIO |= state->antenna_gpio;
5917 else
5918 state->m_GPIO &= ~state->antenna_gpio;
5919 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005920 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005921 if (status < 0)
5922 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005923 return status;
5924}
5925
5926
5927static int PowerDownDevice(struct drxk_state *state)
5928{
5929 /* Power down to requested mode */
5930 /* Backup some register settings */
5931 /* Set pins with possible pull-ups connected to them in input mode */
5932 /* Analog power down */
5933 /* ADC power down */
5934 /* Power down device */
5935 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005936
5937 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005938 if (state->m_bPDownOpenBridge) {
5939 /* Open I2C bridge before power down of DRXK */
5940 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005941 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005942 goto error;
5943 }
5944 /* driver 0.9.0 */
5945 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005946 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005947 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005948
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005949 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5950 if (status < 0)
5951 goto error;
5952 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5953 if (status < 0)
5954 goto error;
5955 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5956 status = HI_CfgCommand(state);
5957error:
5958 if (status < 0)
5959 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5960
5961 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005962}
5963
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005964static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005965{
5966 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005967 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005968
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005969 dprintk(1, "\n");
5970
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005971 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5972 if (err < 0) {
5973 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005974 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005975 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005976 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005977 return err;
5978 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005979 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005980 release_firmware(fw);
5981 return err;
5982}
5983
5984static int init_drxk(struct drxk_state *state)
5985{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005986 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005987 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005988 u16 driverVersion;
5989
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005990 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005991 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005992 status = PowerUpDevice(state);
5993 if (status < 0)
5994 goto error;
5995 status = DRXX_Open(state);
5996 if (status < 0)
5997 goto error;
5998 /* Soft reset of OFDM-, sys- and osc-clockdomain */
5999 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);
6000 if (status < 0)
6001 goto error;
6002 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6003 if (status < 0)
6004 goto error;
6005 /* TODO is this needed, if yes how much delay in worst case scenario */
6006 msleep(1);
6007 state->m_DRXK_A3_PATCH_CODE = true;
6008 status = GetDeviceCapabilities(state);
6009 if (status < 0)
6010 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006011
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006012 /* Bridge delay, uses oscilator clock */
6013 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6014 /* SDA brdige delay */
6015 state->m_HICfgBridgeDelay =
6016 (u16) ((state->m_oscClockFreq / 1000) *
6017 HI_I2C_BRIDGE_DELAY) / 1000;
6018 /* Clipping */
6019 if (state->m_HICfgBridgeDelay >
6020 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006021 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006022 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6023 }
6024 /* SCL bridge delay, same as SDA for now */
6025 state->m_HICfgBridgeDelay +=
6026 state->m_HICfgBridgeDelay <<
6027 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006028
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006029 status = InitHI(state);
6030 if (status < 0)
6031 goto error;
6032 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006033#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006034 if (!(state->m_DRXK_A1_ROM_CODE)
6035 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006036#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006037 {
6038 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6039 if (status < 0)
6040 goto error;
6041 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006042
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006043 /* disable MPEG port */
6044 status = MPEGTSDisable(state);
6045 if (status < 0)
6046 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006047
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006048 /* Stop AUD and SCU */
6049 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6050 if (status < 0)
6051 goto error;
6052 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6053 if (status < 0)
6054 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006055
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006056 /* enable token-ring bus through OFDM block for possible ucode upload */
6057 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6058 if (status < 0)
6059 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006060
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006061 /* include boot loader section */
6062 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6063 if (status < 0)
6064 goto error;
6065 status = BLChainCmd(state, 0, 6, 100);
6066 if (status < 0)
6067 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006068
Mauro Carvalho Chehabda989e02011-07-24 09:25:39 -03006069 if (state->microcode_name)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006070 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006071
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006072 /* disable token-ring bus through OFDM block for possible ucode upload */
6073 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6074 if (status < 0)
6075 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006076
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006077 /* Run SCU for a little while to initialize microcode version numbers */
6078 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6079 if (status < 0)
6080 goto error;
6081 status = DRXX_Open(state);
6082 if (status < 0)
6083 goto error;
6084 /* added for test */
6085 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006086
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006087 powerMode = DRXK_POWER_DOWN_OFDM;
6088 status = CtrlPowerMode(state, &powerMode);
6089 if (status < 0)
6090 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006091
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006092 /* Stamp driver version number in SCU data RAM in BCD code
6093 Done to enable field application engineers to retreive drxdriver version
6094 via I2C from SCU RAM.
6095 Not using SCU command interface for SCU register access since no
6096 microcode may be present.
6097 */
6098 driverVersion =
6099 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6100 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6101 ((DRXK_VERSION_MAJOR % 10) << 4) +
6102 (DRXK_VERSION_MINOR % 10);
6103 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6104 if (status < 0)
6105 goto error;
6106 driverVersion =
6107 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6108 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6109 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6110 (DRXK_VERSION_PATCH % 10);
6111 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6112 if (status < 0)
6113 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006114
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006115 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6116 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6117 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006118
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006119 /* Dirty fix of default values for ROM/PATCH microcode
6120 Dirty because this fix makes it impossible to setup suitable values
6121 before calling DRX_Open. This solution requires changes to RF AGC speed
6122 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006123
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006124 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006125
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006126 /* Reset driver debug flags to 0 */
6127 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6128 if (status < 0)
6129 goto error;
6130 /* driver 0.9.0 */
6131 /* Setup FEC OC:
6132 NOTE: No more full FEC resets allowed afterwards!! */
6133 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6134 if (status < 0)
6135 goto error;
6136 /* MPEGTS functions are still the same */
6137 status = MPEGTSDtoInit(state);
6138 if (status < 0)
6139 goto error;
6140 status = MPEGTSStop(state);
6141 if (status < 0)
6142 goto error;
6143 status = MPEGTSConfigurePolarity(state);
6144 if (status < 0)
6145 goto error;
6146 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6147 if (status < 0)
6148 goto error;
6149 /* added: configure GPIO */
6150 status = WriteGPIO(state);
6151 if (status < 0)
6152 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006153
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006154 state->m_DrxkState = DRXK_STOPPED;
6155
6156 if (state->m_bPowerDown) {
6157 status = PowerDownDevice(state);
6158 if (status < 0)
6159 goto error;
6160 state->m_DrxkState = DRXK_POWERED_DOWN;
6161 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006162 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006163 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006164error:
6165 if (status < 0)
6166 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006167
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006168 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006169}
6170
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006171static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006172{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006173 struct drxk_state *state = fe->demodulator_priv;
6174
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006175 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006176 kfree(state);
6177}
6178
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006179static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006180{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006181 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006182
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006183 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006184 ShutDown(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006185 return 0;
6186}
6187
Oliver Endrissebc7de22011-07-03 13:49:44 -03006188static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006189{
6190 struct drxk_state *state = fe->demodulator_priv;
6191
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006192 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006193 return ConfigureI2CBridge(state, enable ? true : false);
6194}
6195
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006196static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006197{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006198 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006199 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006200 struct drxk_state *state = fe->demodulator_priv;
6201 u32 IF;
6202
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006203 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006204
6205 if (!fe->ops.tuner_ops.get_if_frequency) {
6206 printk(KERN_ERR
6207 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6208 return -EINVAL;
6209 }
6210
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006211 if (fe->ops.i2c_gate_ctrl)
6212 fe->ops.i2c_gate_ctrl(fe, 1);
6213 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006214 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006215 if (fe->ops.i2c_gate_ctrl)
6216 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006217
6218 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006219 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006220
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006221 if (old_delsys != delsys) {
6222 ShutDown(state);
6223 switch (delsys) {
6224 case SYS_DVBC_ANNEX_A:
6225 case SYS_DVBC_ANNEX_C:
6226 if (!state->m_hasDVBC)
6227 return -EINVAL;
6228 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6229 if (state->m_itut_annex_c)
6230 SetOperationMode(state, OM_QAM_ITU_C);
6231 else
6232 SetOperationMode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006233 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006234 case SYS_DVBT:
6235 if (!state->m_hasDVBT)
6236 return -EINVAL;
6237 SetOperationMode(state, OM_DVBT);
6238 break;
6239 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006240 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006241 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006242 }
6243
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006244 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006245 Start(state, 0, IF);
6246
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006247 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006248
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006249 return 0;
6250}
6251
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006252static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6253{
6254 struct drxk_state *state = fe->demodulator_priv;
6255 u32 stat;
6256
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006257 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006258 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006259 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006260 if (stat == MPEG_LOCK)
6261 *status |= 0x1f;
6262 if (stat == FEC_LOCK)
6263 *status |= 0x0f;
6264 if (stat == DEMOD_LOCK)
6265 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006266 return 0;
6267}
6268
6269static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6270{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006271 dprintk(1, "\n");
6272
Oliver Endrissebc7de22011-07-03 13:49:44 -03006273 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006274 return 0;
6275}
6276
Oliver Endrissebc7de22011-07-03 13:49:44 -03006277static int drxk_read_signal_strength(struct dvb_frontend *fe,
6278 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006279{
6280 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006281 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006282
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006283 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006284 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006285 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006286 return 0;
6287}
6288
6289static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6290{
6291 struct drxk_state *state = fe->demodulator_priv;
6292 s32 snr2;
6293
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006294 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006295 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006296 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006297 return 0;
6298}
6299
6300static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6301{
6302 struct drxk_state *state = fe->demodulator_priv;
6303 u16 err;
6304
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006305 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006306 DVBTQAMGetAccPktErr(state, &err);
6307 *ucblocks = (u32) err;
6308 return 0;
6309}
6310
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006311static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006312 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006313{
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006314 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006315
6316 dprintk(1, "\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006317 switch (p->delivery_system) {
6318 case SYS_DVBC_ANNEX_A:
6319 case SYS_DVBC_ANNEX_C:
6320 sets->min_delay_ms = 3000;
6321 sets->max_drift = 0;
6322 sets->step_size = 0;
6323 return 0;
6324 default:
6325 /*
6326 * For DVB-T, let it use the default DVB core way, that is:
6327 * fepriv->step_size = fe->ops.info.frequency_stepsize * 2
6328 */
6329 return -EINVAL;
6330 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006331}
6332
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006333static struct dvb_frontend_ops drxk_ops = {
6334 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006335 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006336 .name = "DRXK",
6337 .frequency_min = 47000000,
6338 .frequency_max = 865000000,
6339 /* For DVB-C */
6340 .symbol_rate_min = 870000,
6341 .symbol_rate_max = 11700000,
6342 /* For DVB-T */
6343 .frequency_stepsize = 166667,
6344
6345 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6346 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6347 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6348 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6349 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6350 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6351 },
6352
6353 .release = drxk_release,
6354 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006355 .i2c_gate_ctrl = drxk_gate_ctrl,
6356
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006357 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006358 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006359
6360 .read_status = drxk_read_status,
6361 .read_ber = drxk_read_ber,
6362 .read_signal_strength = drxk_read_signal_strength,
6363 .read_snr = drxk_read_snr,
6364 .read_ucblocks = drxk_read_ucblocks,
6365};
6366
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006367struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006368 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006369{
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006370 int n;
6371
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006372 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006373 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006374
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006375 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006376 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006377 if (!state)
6378 return NULL;
6379
Oliver Endrissebc7de22011-07-03 13:49:44 -03006380 state->i2c = i2c;
6381 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006382 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006383 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006384 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006385 state->antenna_gpio = config->antenna_gpio;
6386 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006387 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006388 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006389
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006390 if (config->dynamic_clk) {
6391 state->m_DVBTStaticCLK = 0;
6392 state->m_DVBCStaticCLK = 0;
6393 } else {
6394 state->m_DVBTStaticCLK = 1;
6395 state->m_DVBCStaticCLK = 1;
6396 }
6397
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006398
6399 if (config->mpeg_out_clk_strength)
6400 state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
6401 else
6402 state->m_TSClockkStrength = 0x06;
6403
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006404 if (config->parallel_ts)
6405 state->m_enableParallel = true;
6406 else
6407 state->m_enableParallel = false;
6408
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006409 /* NOTE: as more UIO bits will be used, add them to the mask */
6410 state->UIO_mask = config->antenna_gpio;
6411
6412 /* Default gpio to DVB-C */
6413 if (!state->antenna_dvbt && state->antenna_gpio)
6414 state->m_GPIO |= state->antenna_gpio;
6415 else
6416 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006417
6418 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006419
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006420 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6421 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006422
6423 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006424 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006425 goto error;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006426
6427 /* Initialize the supported delivery systems */
6428 n = 0;
6429 if (state->m_hasDVBC) {
6430 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6431 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6432 strlcat(state->frontend.ops.info.name, " DVB-C",
6433 sizeof(state->frontend.ops.info.name));
6434 }
6435 if (state->m_hasDVBT) {
6436 state->frontend.ops.delsys[n++] = SYS_DVBT;
6437 strlcat(state->frontend.ops.info.name, " DVB-T",
6438 sizeof(state->frontend.ops.info.name));
6439 }
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006440
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006441 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006442 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006443
6444error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006445 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006446 kfree(state);
6447 return NULL;
6448}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006449EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006450
6451MODULE_DESCRIPTION("DRX-K driver");
6452MODULE_AUTHOR("Ralph Metzler");
6453MODULE_LICENSE("GPL");