blob: d25b0d20038b761cda3d8ea75c56186d880ed1c7 [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;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001182
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03001183 dprintk(1, ": mpeg %s, %s mode\n",
1184 mpegEnable ? "enable" : "disable",
1185 state->m_enableParallel ? "parallel" : "serial");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001186
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001187 /* stop lock indicator process */
1188 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1189 if (status < 0)
1190 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001191
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001192 /* MPEG TS pad configuration */
1193 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1194 if (status < 0)
1195 goto error;
1196
1197 if (mpegEnable == false) {
1198 /* Set MPEG TS pads to inputmode */
1199 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1200 if (status < 0)
1201 goto error;
1202 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1203 if (status < 0)
1204 goto error;
1205 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1206 if (status < 0)
1207 goto error;
1208 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1209 if (status < 0)
1210 goto error;
1211 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1212 if (status < 0)
1213 goto error;
1214 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1215 if (status < 0)
1216 goto error;
1217 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1218 if (status < 0)
1219 goto error;
1220 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1221 if (status < 0)
1222 goto error;
1223 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1224 if (status < 0)
1225 goto error;
1226 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1227 if (status < 0)
1228 goto error;
1229 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1230 if (status < 0)
1231 goto error;
1232 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1233 if (status < 0)
1234 goto error;
1235 } else {
1236 /* Enable MPEG output */
1237 sioPdrMdxCfg =
1238 ((state->m_TSDataStrength <<
1239 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1240 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1241 SIO_PDR_MCLK_CFG_DRIVE__B) |
1242 0x0003);
1243
1244 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1245 if (status < 0)
1246 goto error;
1247 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
1248 if (status < 0)
1249 goto error;
1250 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
1251 if (status < 0)
1252 goto error;
1253 if (state->m_enableParallel == true) {
1254 /* paralel -> enable MD1 to MD7 */
1255 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001256 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001257 goto error;
1258 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001259 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001260 goto error;
1261 status = write16(state, SIO_PDR_MD3_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_MD4_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_MD5_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_MD6_CFG__A, sioPdrMdxCfg);
1271 if (status < 0)
1272 goto error;
1273 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1274 if (status < 0)
1275 goto error;
1276 } else {
1277 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1278 SIO_PDR_MD0_CFG_DRIVE__B)
1279 | 0x0003);
1280 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001281 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001282 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001283 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001284 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001285 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001286 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001287 status = write16(state, SIO_PDR_MD3_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_MD4_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_MD5_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_MD6_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_MD7_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;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001302 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001303 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001304 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001305 goto error;
1306 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001307 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001308 goto error;
1309 }
1310 /* Enable MB output over MPEG pads and ctl input */
1311 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1312 if (status < 0)
1313 goto error;
1314 /* Write nomagic word to enable pdr reg write */
1315 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1316error:
1317 if (status < 0)
1318 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001319 return status;
1320}
1321
1322static int MPEGTSDisable(struct drxk_state *state)
1323{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001324 dprintk(1, "\n");
1325
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001326 return MPEGTSConfigurePins(state, false);
1327}
1328
1329static int BLChainCmd(struct drxk_state *state,
1330 u16 romOffset, u16 nrOfElements, u32 timeOut)
1331{
1332 u16 blStatus = 0;
1333 int status;
1334 unsigned long end;
1335
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001336 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001337 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001338 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1339 if (status < 0)
1340 goto error;
1341 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1342 if (status < 0)
1343 goto error;
1344 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1345 if (status < 0)
1346 goto error;
1347 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1348 if (status < 0)
1349 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001350
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001351 end = jiffies + msecs_to_jiffies(timeOut);
1352 do {
1353 msleep(1);
1354 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1355 if (status < 0)
1356 goto error;
1357 } while ((blStatus == 0x1) &&
1358 ((time_is_after_jiffies(end))));
1359
1360 if (blStatus == 0x1) {
1361 printk(KERN_ERR "drxk: SIO not ready\n");
1362 status = -EINVAL;
1363 goto error2;
1364 }
1365error:
1366 if (status < 0)
1367 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1368error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001369 mutex_unlock(&state->mutex);
1370 return status;
1371}
1372
1373
1374static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001375 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001376{
1377 const u8 *pSrc = pMCImage;
1378 u16 Flags;
1379 u16 Drain;
1380 u32 Address;
1381 u16 nBlocks;
1382 u16 BlockSize;
1383 u16 BlockCRC;
1384 u32 offset = 0;
1385 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001386 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001387
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001388 dprintk(1, "\n");
1389
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001390 /* down the drain (we don care about MAGIC_WORD) */
1391 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001392 pSrc += sizeof(u16);
1393 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001394 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001395 pSrc += sizeof(u16);
1396 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001397
1398 for (i = 0; i < nBlocks; i += 1) {
1399 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001400 (pSrc[2] << 8) | pSrc[3];
1401 pSrc += sizeof(u32);
1402 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001403
1404 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001405 pSrc += sizeof(u16);
1406 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001407
1408 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001409 pSrc += sizeof(u16);
1410 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001411
1412 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001413 pSrc += sizeof(u16);
1414 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001415
1416 if (offset + BlockSize > Length) {
1417 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1418 return -EINVAL;
1419 }
1420
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001421 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001422 if (status < 0) {
1423 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001424 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001425 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001426 pSrc += BlockSize;
1427 offset += BlockSize;
1428 }
1429 return status;
1430}
1431
1432static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1433{
1434 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001435 u16 data = 0;
1436 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001437 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1438 unsigned long end;
1439
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001440 dprintk(1, "\n");
1441
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001442 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001443 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001444 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1445 }
1446
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001447 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1448 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001449 /* tokenring already has correct status */
1450 return status;
1451 }
1452 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001453 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001454
Oliver Endrissebc7de22011-07-03 13:49:44 -03001455 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001456 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001457 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001458 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001459 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001460 msleep(1);
1461 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001462 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001463 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001464 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001465 }
1466 return status;
1467}
1468
1469static int MPEGTSStop(struct drxk_state *state)
1470{
1471 int status = 0;
1472 u16 fecOcSncMode = 0;
1473 u16 fecOcIprMode = 0;
1474
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001475 dprintk(1, "\n");
1476
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001477 /* Gracefull shutdown (byte boundaries) */
1478 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1479 if (status < 0)
1480 goto error;
1481 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1482 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1483 if (status < 0)
1484 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001485
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001486 /* Suppress MCLK during absence of data */
1487 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1488 if (status < 0)
1489 goto error;
1490 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1491 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1492
1493error:
1494 if (status < 0)
1495 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1496
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001497 return status;
1498}
1499
1500static int scu_command(struct drxk_state *state,
1501 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001502 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001503{
1504#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1505#error DRXK register mapping no longer compatible with this routine!
1506#endif
1507 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001508 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001509 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001510 u8 buffer[34];
1511 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001512 const char *p;
1513 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001514
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001515 dprintk(1, "\n");
1516
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001517 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1518 ((resultLen > 0) && (result == NULL)))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001519 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001520
1521 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001522
1523 /* assume that the command register is ready
1524 since it is checked afterwards */
1525 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1526 buffer[cnt++] = (parameter[ii] & 0xFF);
1527 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1528 }
1529 buffer[cnt++] = (cmd & 0xFF);
1530 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1531
1532 write_block(state, SCU_RAM_PARAM_0__A -
1533 (parameterLen - 1), cnt, buffer);
1534 /* Wait until SCU has processed command */
1535 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001536 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001537 msleep(1);
1538 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1539 if (status < 0)
1540 goto error;
1541 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1542 if (curCmd != DRX_SCU_READY) {
1543 printk(KERN_ERR "drxk: SCU not ready\n");
1544 status = -EIO;
1545 goto error2;
1546 }
1547 /* read results */
1548 if ((resultLen > 0) && (result != NULL)) {
1549 s16 err;
1550 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001551
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001552 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1553 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001554 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001555 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001556 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001557
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001558 /* Check if an error was reported by SCU */
1559 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001560 if (err >= 0)
1561 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001562
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001563 /* check for the known error codes */
1564 switch (err) {
1565 case SCU_RESULT_UNKCMD:
1566 p = "SCU_RESULT_UNKCMD";
1567 break;
1568 case SCU_RESULT_UNKSTD:
1569 p = "SCU_RESULT_UNKSTD";
1570 break;
1571 case SCU_RESULT_SIZE:
1572 p = "SCU_RESULT_SIZE";
1573 break;
1574 case SCU_RESULT_INVPAR:
1575 p = "SCU_RESULT_INVPAR";
1576 break;
1577 default: /* Other negative values are errors */
1578 sprintf(errname, "ERROR: %d\n", err);
1579 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001580 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001581 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1582 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1583 status = -EINVAL;
1584 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001585 }
1586
1587error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001588 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001589 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001590error2:
1591 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001592 return status;
1593}
1594
1595static int SetIqmAf(struct drxk_state *state, bool active)
1596{
1597 u16 data = 0;
1598 int status;
1599
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001600 dprintk(1, "\n");
1601
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001602 /* Configure IQM */
1603 status = read16(state, IQM_AF_STDBY__A, &data);
1604 if (status < 0)
1605 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001606
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001607 if (!active) {
1608 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1609 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1610 | IQM_AF_STDBY_STDBY_PD_STANDBY
1611 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1612 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1613 } else {
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 );
1620 }
1621 status = write16(state, IQM_AF_STDBY__A, data);
1622
1623error:
1624 if (status < 0)
1625 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001626 return status;
1627}
1628
Oliver Endrissebc7de22011-07-03 13:49:44 -03001629static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001630{
1631 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001632 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001633
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001634 dprintk(1, "\n");
1635
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001636 /* Check arguments */
1637 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001638 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001639
1640 switch (*mode) {
1641 case DRX_POWER_UP:
1642 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1643 break;
1644 case DRXK_POWER_DOWN_OFDM:
1645 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1646 break;
1647 case DRXK_POWER_DOWN_CORE:
1648 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1649 break;
1650 case DRXK_POWER_DOWN_PLL:
1651 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1652 break;
1653 case DRX_POWER_DOWN:
1654 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1655 break;
1656 default:
1657 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001658 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001659 }
1660
1661 /* If already in requested power mode, do nothing */
1662 if (state->m_currentPowerMode == *mode)
1663 return 0;
1664
1665 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001666 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001667 status = PowerUpDevice(state);
1668 if (status < 0)
1669 goto error;
1670 status = DVBTEnableOFDMTokenRing(state, true);
1671 if (status < 0)
1672 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001673 }
1674
1675 if (*mode == DRX_POWER_UP) {
1676 /* Restore analog & pin configuartion */
1677 } else {
1678 /* Power down to requested mode */
1679 /* Backup some register settings */
1680 /* Set pins with possible pull-ups connected
1681 to them in input mode */
1682 /* Analog power down */
1683 /* ADC power down */
1684 /* Power down device */
1685 /* stop all comm_exec */
1686 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001687 switch (state->m_OperationMode) {
1688 case OM_DVBT:
1689 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001690 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001691 goto error;
1692 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001693 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001694 goto error;
1695 break;
1696 case OM_QAM_ITU_A:
1697 case OM_QAM_ITU_C:
1698 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001699 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001700 goto error;
1701 status = PowerDownQAM(state);
1702 if (status < 0)
1703 goto error;
1704 break;
1705 default:
1706 break;
1707 }
1708 status = DVBTEnableOFDMTokenRing(state, false);
1709 if (status < 0)
1710 goto error;
1711 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1712 if (status < 0)
1713 goto error;
1714 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1715 if (status < 0)
1716 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001717
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001718 if (*mode != DRXK_POWER_DOWN_OFDM) {
1719 state->m_HICfgCtrl |=
1720 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1721 status = HI_CfgCommand(state);
1722 if (status < 0)
1723 goto error;
1724 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001725 }
1726 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001727
1728error:
1729 if (status < 0)
1730 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1731
Oliver Endrissebc7de22011-07-03 13:49:44 -03001732 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001733}
1734
1735static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1736{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001737 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001738 u16 cmdResult = 0;
1739 u16 data = 0;
1740 int status;
1741
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001742 dprintk(1, "\n");
1743
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001744 status = read16(state, SCU_COMM_EXEC__A, &data);
1745 if (status < 0)
1746 goto error;
1747 if (data == SCU_COMM_EXEC_ACTIVE) {
1748 /* Send OFDM stop command */
1749 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 -03001750 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001751 goto error;
1752 /* Send OFDM reset command */
1753 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1754 if (status < 0)
1755 goto error;
1756 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001757
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001758 /* Reset datapath for OFDM, processors first */
1759 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1760 if (status < 0)
1761 goto error;
1762 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1763 if (status < 0)
1764 goto error;
1765 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1766 if (status < 0)
1767 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001768
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001769 /* powerdown AFE */
1770 status = SetIqmAf(state, false);
1771 if (status < 0)
1772 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001773
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001774 /* powerdown to OFDM mode */
1775 if (setPowerMode) {
1776 status = CtrlPowerMode(state, &powerMode);
1777 if (status < 0)
1778 goto error;
1779 }
1780error:
1781 if (status < 0)
1782 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001783 return status;
1784}
1785
Oliver Endrissebc7de22011-07-03 13:49:44 -03001786static int SetOperationMode(struct drxk_state *state,
1787 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001788{
1789 int status = 0;
1790
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001791 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001792 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001793 Stop and power down previous standard
1794 TODO investigate total power down instead of partial
1795 power down depending on "previous" standard.
1796 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001797
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001798 /* disable HW lock indicator */
1799 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1800 if (status < 0)
1801 goto error;
1802
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001803 /* Device is already at the required mode */
1804 if (state->m_OperationMode == oMode)
1805 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001806
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001807 switch (state->m_OperationMode) {
1808 /* OM_NONE was added for start up */
1809 case OM_NONE:
1810 break;
1811 case OM_DVBT:
1812 status = MPEGTSStop(state);
1813 if (status < 0)
1814 goto error;
1815 status = PowerDownDVBT(state, true);
1816 if (status < 0)
1817 goto error;
1818 state->m_OperationMode = OM_NONE;
1819 break;
1820 case OM_QAM_ITU_A: /* fallthrough */
1821 case OM_QAM_ITU_C:
1822 status = MPEGTSStop(state);
1823 if (status < 0)
1824 goto error;
1825 status = PowerDownQAM(state);
1826 if (status < 0)
1827 goto error;
1828 state->m_OperationMode = OM_NONE;
1829 break;
1830 case OM_QAM_ITU_B:
1831 default:
1832 status = -EINVAL;
1833 goto error;
1834 }
1835
1836 /*
1837 Power up new standard
1838 */
1839 switch (oMode) {
1840 case OM_DVBT:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001841 dprintk(1, ": DVB-T\n");
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001842 state->m_OperationMode = oMode;
1843 status = SetDVBTStandard(state, oMode);
1844 if (status < 0)
1845 goto error;
1846 break;
1847 case OM_QAM_ITU_A: /* fallthrough */
1848 case OM_QAM_ITU_C:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001849 dprintk(1, ": DVB-C Annex %c\n",
1850 (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001851 state->m_OperationMode = oMode;
1852 status = SetQAMStandard(state, oMode);
1853 if (status < 0)
1854 goto error;
1855 break;
1856 case OM_QAM_ITU_B:
1857 default:
1858 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001859 }
1860error:
1861 if (status < 0)
1862 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1863 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001864}
1865
1866static int Start(struct drxk_state *state, s32 offsetFreq,
1867 s32 IntermediateFrequency)
1868{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001869 int status = -EINVAL;
1870
1871 u16 IFreqkHz;
1872 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001873
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001874 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001875 if (state->m_DrxkState != DRXK_STOPPED &&
1876 state->m_DrxkState != DRXK_DTV_STARTED)
1877 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001878
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03001879 state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001880
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001881 if (IntermediateFrequency < 0) {
1882 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1883 IntermediateFrequency = -IntermediateFrequency;
1884 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001885
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001886 switch (state->m_OperationMode) {
1887 case OM_QAM_ITU_A:
1888 case OM_QAM_ITU_C:
1889 IFreqkHz = (IntermediateFrequency / 1000);
1890 status = SetQAM(state, IFreqkHz, OffsetkHz);
1891 if (status < 0)
1892 goto error;
1893 state->m_DrxkState = DRXK_DTV_STARTED;
1894 break;
1895 case OM_DVBT:
1896 IFreqkHz = (IntermediateFrequency / 1000);
1897 status = MPEGTSStop(state);
1898 if (status < 0)
1899 goto error;
1900 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1901 if (status < 0)
1902 goto error;
1903 status = DVBTStart(state);
1904 if (status < 0)
1905 goto error;
1906 state->m_DrxkState = DRXK_DTV_STARTED;
1907 break;
1908 default:
1909 break;
1910 }
1911error:
1912 if (status < 0)
1913 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001914 return status;
1915}
1916
1917static int ShutDown(struct drxk_state *state)
1918{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001919 dprintk(1, "\n");
1920
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001921 MPEGTSStop(state);
1922 return 0;
1923}
1924
Oliver Endrissebc7de22011-07-03 13:49:44 -03001925static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1926 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001927{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001928 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001929
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001930 dprintk(1, "\n");
1931
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001932 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001933 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001934
1935 *pLockStatus = NOT_LOCKED;
1936
1937 /* define the SCU command code */
1938 switch (state->m_OperationMode) {
1939 case OM_QAM_ITU_A:
1940 case OM_QAM_ITU_B:
1941 case OM_QAM_ITU_C:
1942 status = GetQAMLockStatus(state, pLockStatus);
1943 break;
1944 case OM_DVBT:
1945 status = GetDVBTLockStatus(state, pLockStatus);
1946 break;
1947 default:
1948 break;
1949 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001950error:
1951 if (status < 0)
1952 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001953 return status;
1954}
1955
1956static int MPEGTSStart(struct drxk_state *state)
1957{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001958 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001959
1960 u16 fecOcSncMode = 0;
1961
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001962 /* Allow OC to sync again */
1963 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1964 if (status < 0)
1965 goto error;
1966 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1967 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1968 if (status < 0)
1969 goto error;
1970 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1971error:
1972 if (status < 0)
1973 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001974 return status;
1975}
1976
1977static int MPEGTSDtoInit(struct drxk_state *state)
1978{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001979 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001980
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001981 dprintk(1, "\n");
1982
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001983 /* Rate integration settings */
1984 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1985 if (status < 0)
1986 goto error;
1987 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1988 if (status < 0)
1989 goto error;
1990 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1991 if (status < 0)
1992 goto error;
1993 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1994 if (status < 0)
1995 goto error;
1996 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
1997 if (status < 0)
1998 goto error;
1999 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2000 if (status < 0)
2001 goto error;
2002 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2003 if (status < 0)
2004 goto error;
2005 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2006 if (status < 0)
2007 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002008
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002009 /* Additional configuration */
2010 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2011 if (status < 0)
2012 goto error;
2013 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2014 if (status < 0)
2015 goto error;
2016 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2017error:
2018 if (status < 0)
2019 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2020
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002021 return status;
2022}
2023
Oliver Endrissebc7de22011-07-03 13:49:44 -03002024static int MPEGTSDtoSetup(struct drxk_state *state,
2025 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002026{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002027 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002028
Oliver Endrissebc7de22011-07-03 13:49:44 -03002029 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2030 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2031 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2032 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2033 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2034 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2035 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002036 u16 fecOcTmdMode = 0;
2037 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002038 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002039 bool staticCLK = false;
2040
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002041 dprintk(1, "\n");
2042
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002043 /* Check insertion of the Reed-Solomon parity bytes */
2044 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2045 if (status < 0)
2046 goto error;
2047 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2048 if (status < 0)
2049 goto error;
2050 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2051 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2052 if (state->m_insertRSByte == true) {
2053 /* enable parity symbol forward */
2054 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2055 /* MVAL disable during parity bytes */
2056 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2057 /* TS burst length to 204 */
2058 fecOcDtoBurstLen = 204;
2059 }
2060
2061 /* Check serial or parrallel output */
2062 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2063 if (state->m_enableParallel == false) {
2064 /* MPEG data output is serial -> set ipr_mode[0] */
2065 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2066 }
2067
2068 switch (oMode) {
2069 case OM_DVBT:
2070 maxBitRate = state->m_DVBTBitrate;
2071 fecOcTmdMode = 3;
2072 fecOcRcnCtlRate = 0xC00000;
2073 staticCLK = state->m_DVBTStaticCLK;
2074 break;
2075 case OM_QAM_ITU_A: /* fallthrough */
2076 case OM_QAM_ITU_C:
2077 fecOcTmdMode = 0x0004;
2078 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2079 maxBitRate = state->m_DVBCBitrate;
2080 staticCLK = state->m_DVBCStaticCLK;
2081 break;
2082 default:
2083 status = -EINVAL;
2084 } /* switch (standard) */
2085 if (status < 0)
2086 goto error;
2087
2088 /* Configure DTO's */
2089 if (staticCLK) {
2090 u32 bitRate = 0;
2091
2092 /* Rational DTO for MCLK source (static MCLK rate),
2093 Dynamic DTO for optimal grouping
2094 (avoid intra-packet gaps),
2095 DTO offset enable to sync TS burst with MSTRT */
2096 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2097 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2098 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2099 FEC_OC_FCT_MODE_VIRT_ENA__M);
2100
2101 /* Check user defined bitrate */
2102 bitRate = maxBitRate;
2103 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2104 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002105 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002106 /* Rational DTO period:
2107 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002108
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002109 Result should be floored,
2110 to make sure >= requested bitrate
2111 */
2112 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2113 * 1000) / bitRate);
2114 if (fecOcDtoPeriod <= 2)
2115 fecOcDtoPeriod = 0;
2116 else
2117 fecOcDtoPeriod -= 2;
2118 fecOcTmdIntUpdRate = 8;
2119 } else {
2120 /* (commonAttr->staticCLK == false) => dynamic mode */
2121 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2122 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2123 fecOcTmdIntUpdRate = 5;
2124 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002125
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002126 /* Write appropriate registers with requested configuration */
2127 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2128 if (status < 0)
2129 goto error;
2130 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2131 if (status < 0)
2132 goto error;
2133 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2134 if (status < 0)
2135 goto error;
2136 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2137 if (status < 0)
2138 goto error;
2139 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2140 if (status < 0)
2141 goto error;
2142 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2143 if (status < 0)
2144 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002145
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002146 /* Rate integration settings */
2147 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2148 if (status < 0)
2149 goto error;
2150 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2151 if (status < 0)
2152 goto error;
2153 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2154error:
2155 if (status < 0)
2156 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002157 return status;
2158}
2159
2160static int MPEGTSConfigurePolarity(struct drxk_state *state)
2161{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002162 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002163
2164 /* Data mask for the output data byte */
2165 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002166 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2167 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2168 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2169 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002170
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002171 dprintk(1, "\n");
2172
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002173 /* Control selective inversion of output bits */
2174 fecOcRegIprInvert &= (~(InvertDataMask));
2175 if (state->m_invertDATA == true)
2176 fecOcRegIprInvert |= InvertDataMask;
2177 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2178 if (state->m_invertERR == true)
2179 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2180 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2181 if (state->m_invertSTR == true)
2182 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2183 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2184 if (state->m_invertVAL == true)
2185 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2186 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2187 if (state->m_invertCLK == true)
2188 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002189
2190 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002191}
2192
2193#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2194
2195static int SetAgcRf(struct drxk_state *state,
2196 struct SCfgAgc *pAgcCfg, bool isDTV)
2197{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002198 int status = -EINVAL;
2199 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002200 struct SCfgAgc *pIfAgcSettings;
2201
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002202 dprintk(1, "\n");
2203
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002204 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002205 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002206
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002207 switch (pAgcCfg->ctrlMode) {
2208 case DRXK_AGC_CTRL_AUTO:
2209 /* Enable RF AGC DAC */
2210 status = read16(state, IQM_AF_STDBY__A, &data);
2211 if (status < 0)
2212 goto error;
2213 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2214 status = write16(state, IQM_AF_STDBY__A, data);
2215 if (status < 0)
2216 goto error;
2217 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2218 if (status < 0)
2219 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002220
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002221 /* Enable SCU RF AGC loop */
2222 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002223
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002224 /* Polarity */
2225 if (state->m_RfAgcPol)
2226 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2227 else
2228 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2229 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2230 if (status < 0)
2231 goto error;
2232
2233 /* Set speed (using complementary reduction value) */
2234 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2235 if (status < 0)
2236 goto error;
2237
2238 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2239 data |= (~(pAgcCfg->speed <<
2240 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2241 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2242
2243 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2244 if (status < 0)
2245 goto error;
2246
2247 if (IsDVBT(state))
2248 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2249 else if (IsQAM(state))
2250 pIfAgcSettings = &state->m_qamIfAgcCfg;
2251 else
2252 pIfAgcSettings = &state->m_atvIfAgcCfg;
2253 if (pIfAgcSettings == NULL) {
2254 status = -EINVAL;
2255 goto error;
2256 }
2257
2258 /* Set TOP, only if IF-AGC is in AUTO mode */
2259 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2260 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002261 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002262 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002263
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002264 /* Cut-Off current */
2265 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2266 if (status < 0)
2267 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002268
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002269 /* Max. output level */
2270 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2271 if (status < 0)
2272 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002273
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002274 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002275
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002276 case DRXK_AGC_CTRL_USER:
2277 /* Enable RF AGC DAC */
2278 status = read16(state, IQM_AF_STDBY__A, &data);
2279 if (status < 0)
2280 goto error;
2281 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2282 status = write16(state, IQM_AF_STDBY__A, data);
2283 if (status < 0)
2284 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002285
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002286 /* Disable SCU RF AGC loop */
2287 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2288 if (status < 0)
2289 goto error;
2290 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2291 if (state->m_RfAgcPol)
2292 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2293 else
2294 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2295 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2296 if (status < 0)
2297 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002298
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002299 /* SCU c.o.c. to 0, enabling full control range */
2300 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2301 if (status < 0)
2302 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002303
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002304 /* Write value to output pin */
2305 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2306 if (status < 0)
2307 goto error;
2308 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002309
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002310 case DRXK_AGC_CTRL_OFF:
2311 /* Disable RF AGC DAC */
2312 status = read16(state, IQM_AF_STDBY__A, &data);
2313 if (status < 0)
2314 goto error;
2315 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2316 status = write16(state, IQM_AF_STDBY__A, data);
2317 if (status < 0)
2318 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002319
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002320 /* Disable SCU RF AGC loop */
2321 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2322 if (status < 0)
2323 goto error;
2324 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2325 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2326 if (status < 0)
2327 goto error;
2328 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002329
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002330 default:
2331 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002332
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002333 }
2334error:
2335 if (status < 0)
2336 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002337 return status;
2338}
2339
2340#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2341
Oliver Endrissebc7de22011-07-03 13:49:44 -03002342static int SetAgcIf(struct drxk_state *state,
2343 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002344{
2345 u16 data = 0;
2346 int status = 0;
2347 struct SCfgAgc *pRfAgcSettings;
2348
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002349 dprintk(1, "\n");
2350
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002351 switch (pAgcCfg->ctrlMode) {
2352 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002353
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002354 /* Enable IF AGC DAC */
2355 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002356 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002357 goto error;
2358 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2359 status = write16(state, IQM_AF_STDBY__A, data);
2360 if (status < 0)
2361 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002362
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002363 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2364 if (status < 0)
2365 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002366
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002367 /* Enable SCU IF AGC loop */
2368 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2369
2370 /* Polarity */
2371 if (state->m_IfAgcPol)
2372 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2373 else
2374 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2375 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2376 if (status < 0)
2377 goto error;
2378
2379 /* Set speed (using complementary reduction value) */
2380 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2381 if (status < 0)
2382 goto error;
2383 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2384 data |= (~(pAgcCfg->speed <<
2385 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2386 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2387
2388 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2389 if (status < 0)
2390 goto error;
2391
2392 if (IsQAM(state))
2393 pRfAgcSettings = &state->m_qamRfAgcCfg;
2394 else
2395 pRfAgcSettings = &state->m_atvRfAgcCfg;
2396 if (pRfAgcSettings == NULL)
2397 return -1;
2398 /* Restore TOP */
2399 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2400 if (status < 0)
2401 goto error;
2402 break;
2403
2404 case DRXK_AGC_CTRL_USER:
2405
2406 /* Enable IF AGC DAC */
2407 status = read16(state, IQM_AF_STDBY__A, &data);
2408 if (status < 0)
2409 goto error;
2410 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2411 status = write16(state, IQM_AF_STDBY__A, data);
2412 if (status < 0)
2413 goto error;
2414
2415 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2416 if (status < 0)
2417 goto error;
2418
2419 /* Disable SCU IF AGC loop */
2420 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2421
2422 /* Polarity */
2423 if (state->m_IfAgcPol)
2424 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2425 else
2426 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2427 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2428 if (status < 0)
2429 goto error;
2430
2431 /* Write value to output pin */
2432 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2433 if (status < 0)
2434 goto error;
2435 break;
2436
2437 case DRXK_AGC_CTRL_OFF:
2438
2439 /* Disable If AGC DAC */
2440 status = read16(state, IQM_AF_STDBY__A, &data);
2441 if (status < 0)
2442 goto error;
2443 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2444 status = write16(state, IQM_AF_STDBY__A, data);
2445 if (status < 0)
2446 goto error;
2447
2448 /* Disable SCU IF AGC loop */
2449 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2450 if (status < 0)
2451 goto error;
2452 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2453 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2454 if (status < 0)
2455 goto error;
2456 break;
2457 } /* switch (agcSettingsIf->ctrlMode) */
2458
2459 /* always set the top to support
2460 configurations without if-loop */
2461 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2462error:
2463 if (status < 0)
2464 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002465 return status;
2466}
2467
2468static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2469{
2470 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002471 int status;
2472 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002473
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002474 dprintk(1, "\n");
2475
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002476 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2477 if (status < 0) {
2478 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2479 return status;
2480 }
2481
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002482 *pValue = 0;
2483
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002484 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2485 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2486 if (Level < 14000)
2487 *pValue = (14000 - Level) / 4;
2488 else
2489 *pValue = 0;
2490
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002491 return status;
2492}
2493
Oliver Endrissebc7de22011-07-03 13:49:44 -03002494static int GetQAMSignalToNoise(struct drxk_state *state,
2495 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002496{
2497 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002498 u16 qamSlErrPower = 0; /* accum. error between
2499 raw and sliced symbols */
2500 u32 qamSlSigPower = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002501 QAM modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002502 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002503
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002504 dprintk(1, "\n");
2505
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002506 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002507
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002508 /* get the register value needed for MER */
2509 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2510 if (status < 0) {
2511 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2512 return -EINVAL;
2513 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002514
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002515 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002516 case QAM_16:
2517 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2518 break;
2519 case QAM_32:
2520 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2521 break;
2522 case QAM_64:
2523 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2524 break;
2525 case QAM_128:
2526 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2527 break;
2528 default:
2529 case QAM_256:
2530 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2531 break;
2532 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002533
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002534 if (qamSlErrPower > 0) {
2535 qamSlMer = Log10Times100(qamSlSigPower) -
2536 Log10Times100((u32) qamSlErrPower);
2537 }
2538 *pSignalToNoise = qamSlMer;
2539
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002540 return status;
2541}
2542
Oliver Endrissebc7de22011-07-03 13:49:44 -03002543static int GetDVBTSignalToNoise(struct drxk_state *state,
2544 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002545{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002546 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002547 u16 regData = 0;
2548 u32 EqRegTdSqrErrI = 0;
2549 u32 EqRegTdSqrErrQ = 0;
2550 u16 EqRegTdSqrErrExp = 0;
2551 u16 EqRegTdTpsPwrOfs = 0;
2552 u16 EqRegTdReqSmbCnt = 0;
2553 u32 tpsCnt = 0;
2554 u32 SqrErrIQ = 0;
2555 u32 a = 0;
2556 u32 b = 0;
2557 u32 c = 0;
2558 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002559 u16 transmissionParams = 0;
2560
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002561 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002562
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002563 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2564 if (status < 0)
2565 goto error;
2566 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2567 if (status < 0)
2568 goto error;
2569 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2570 if (status < 0)
2571 goto error;
2572 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2573 if (status < 0)
2574 goto error;
2575 /* Extend SQR_ERR_I operational range */
2576 EqRegTdSqrErrI = (u32) regData;
2577 if ((EqRegTdSqrErrExp > 11) &&
2578 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2579 EqRegTdSqrErrI += 0x00010000UL;
2580 }
2581 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2582 if (status < 0)
2583 goto error;
2584 /* Extend SQR_ERR_Q operational range */
2585 EqRegTdSqrErrQ = (u32) regData;
2586 if ((EqRegTdSqrErrExp > 11) &&
2587 (EqRegTdSqrErrQ < 0x00000FFFUL))
2588 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002589
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002590 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2591 if (status < 0)
2592 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002593
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002594 /* Check input data for MER */
2595
2596 /* MER calculation (in 0.1 dB) without math.h */
2597 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2598 iMER = 0;
2599 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2600 /* No error at all, this must be the HW reset value
2601 * Apparently no first measurement yet
2602 * Set MER to 0.0 */
2603 iMER = 0;
2604 } else {
2605 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2606 EqRegTdSqrErrExp;
2607 if ((transmissionParams &
2608 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2609 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2610 tpsCnt = 17;
2611 else
2612 tpsCnt = 68;
2613
2614 /* IMER = 100 * log10 (x)
2615 where x = (EqRegTdTpsPwrOfs^2 *
2616 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2617
2618 => IMER = a + b -c
2619 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2620 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2621 c = 100 * log10 (SqrErrIQ)
2622 */
2623
2624 /* log(x) x = 9bits * 9bits->18 bits */
2625 a = Log10Times100(EqRegTdTpsPwrOfs *
2626 EqRegTdTpsPwrOfs);
2627 /* log(x) x = 16bits * 7bits->23 bits */
2628 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2629 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2630 c = Log10Times100(SqrErrIQ);
2631
2632 iMER = a + b;
2633 /* No negative MER, clip to zero */
2634 if (iMER > c)
2635 iMER -= c;
2636 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002637 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002638 }
2639 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002640
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002641error:
2642 if (status < 0)
2643 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002644 return status;
2645}
2646
2647static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2648{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002649 dprintk(1, "\n");
2650
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002651 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002652 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002653 case OM_DVBT:
2654 return GetDVBTSignalToNoise(state, pSignalToNoise);
2655 case OM_QAM_ITU_A:
2656 case OM_QAM_ITU_C:
2657 return GetQAMSignalToNoise(state, pSignalToNoise);
2658 default:
2659 break;
2660 }
2661 return 0;
2662}
2663
2664#if 0
2665static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2666{
2667 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2668 int status = 0;
2669
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002670 dprintk(1, "\n");
2671
Oliver Endrissebc7de22011-07-03 13:49:44 -03002672 static s32 QE_SN[] = {
2673 51, /* QPSK 1/2 */
2674 69, /* QPSK 2/3 */
2675 79, /* QPSK 3/4 */
2676 89, /* QPSK 5/6 */
2677 97, /* QPSK 7/8 */
2678 108, /* 16-QAM 1/2 */
2679 131, /* 16-QAM 2/3 */
2680 146, /* 16-QAM 3/4 */
2681 156, /* 16-QAM 5/6 */
2682 160, /* 16-QAM 7/8 */
2683 165, /* 64-QAM 1/2 */
2684 187, /* 64-QAM 2/3 */
2685 202, /* 64-QAM 3/4 */
2686 216, /* 64-QAM 5/6 */
2687 225, /* 64-QAM 7/8 */
2688 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002689
2690 *pQuality = 0;
2691
2692 do {
2693 s32 SignalToNoise = 0;
2694 u16 Constellation = 0;
2695 u16 CodeRate = 0;
2696 u32 SignalToNoiseRel;
2697 u32 BERQuality;
2698
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002699 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2700 if (status < 0)
2701 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002702 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002703 if (status < 0)
2704 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002705 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2706
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002707 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002708 if (status < 0)
2709 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002710 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2711
2712 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2713 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2714 break;
2715 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002716 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002717 BERQuality = 100;
2718
Oliver Endrissebc7de22011-07-03 13:49:44 -03002719 if (SignalToNoiseRel < -70)
2720 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002721 else if (SignalToNoiseRel < 30)
2722 *pQuality = ((SignalToNoiseRel + 70) *
2723 BERQuality) / 100;
2724 else
2725 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002726 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002727 return 0;
2728};
2729
Oliver Endrissebc7de22011-07-03 13:49:44 -03002730static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002731{
2732 int status = 0;
2733 *pQuality = 0;
2734
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002735 dprintk(1, "\n");
2736
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002737 do {
2738 u32 SignalToNoise = 0;
2739 u32 BERQuality = 100;
2740 u32 SignalToNoiseRel = 0;
2741
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002742 status = GetQAMSignalToNoise(state, &SignalToNoise);
2743 if (status < 0)
2744 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002745
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002746 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002747 case QAM_16:
2748 SignalToNoiseRel = SignalToNoise - 200;
2749 break;
2750 case QAM_32:
2751 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002752 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002753 case QAM_64:
2754 SignalToNoiseRel = SignalToNoise - 260;
2755 break;
2756 case QAM_128:
2757 SignalToNoiseRel = SignalToNoise - 290;
2758 break;
2759 default:
2760 case QAM_256:
2761 SignalToNoiseRel = SignalToNoise - 320;
2762 break;
2763 }
2764
2765 if (SignalToNoiseRel < -70)
2766 *pQuality = 0;
2767 else if (SignalToNoiseRel < 30)
2768 *pQuality = ((SignalToNoiseRel + 70) *
2769 BERQuality) / 100;
2770 else
2771 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002772 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002773
2774 return status;
2775}
2776
2777static int GetQuality(struct drxk_state *state, s32 *pQuality)
2778{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002779 dprintk(1, "\n");
2780
Oliver Endrissebc7de22011-07-03 13:49:44 -03002781 switch (state->m_OperationMode) {
2782 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002783 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002784 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002785 return GetDVBCQuality(state, pQuality);
2786 default:
2787 break;
2788 }
2789
2790 return 0;
2791}
2792#endif
2793
2794/* Free data ram in SIO HI */
2795#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2796#define SIO_HI_RA_RAM_USR_END__A 0x420060
2797
2798#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2799#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2800#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2801#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2802
2803#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2804#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2805#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2806
2807static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2808{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002809 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002810
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002811 dprintk(1, "\n");
2812
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002813 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002814 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002815 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002816 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002817
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002818 if (state->no_i2c_bridge)
2819 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002820
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002821 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2822 if (status < 0)
2823 goto error;
2824 if (bEnableBridge) {
2825 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 -03002826 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002827 goto error;
2828 } else {
2829 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2830 if (status < 0)
2831 goto error;
2832 }
2833
2834 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2835
2836error:
2837 if (status < 0)
2838 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002839 return status;
2840}
2841
Oliver Endrissebc7de22011-07-03 13:49:44 -03002842static int SetPreSaw(struct drxk_state *state,
2843 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002844{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002845 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002846
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002847 dprintk(1, "\n");
2848
Oliver Endrissebc7de22011-07-03 13:49:44 -03002849 if ((pPreSawCfg == NULL)
2850 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002851 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002852
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002853 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002854error:
2855 if (status < 0)
2856 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002857 return status;
2858}
2859
2860static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002861 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002862{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002863 u16 blStatus = 0;
2864 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2865 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2866 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002867 unsigned long end;
2868
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002869 dprintk(1, "\n");
2870
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002871 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002872 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2873 if (status < 0)
2874 goto error;
2875 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2876 if (status < 0)
2877 goto error;
2878 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2879 if (status < 0)
2880 goto error;
2881 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2882 if (status < 0)
2883 goto error;
2884 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2885 if (status < 0)
2886 goto error;
2887 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2888 if (status < 0)
2889 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002890
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002891 end = jiffies + msecs_to_jiffies(timeOut);
2892 do {
2893 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2894 if (status < 0)
2895 goto error;
2896 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2897 if (blStatus == 0x1) {
2898 printk(KERN_ERR "drxk: SIO not ready\n");
2899 status = -EINVAL;
2900 goto error2;
2901 }
2902error:
2903 if (status < 0)
2904 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2905error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002906 mutex_unlock(&state->mutex);
2907 return status;
2908
2909}
2910
Oliver Endrissebc7de22011-07-03 13:49:44 -03002911static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002912{
2913 u16 data = 0;
2914 int status;
2915
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002916 dprintk(1, "\n");
2917
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002918 /* Start measurement */
2919 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2920 if (status < 0)
2921 goto error;
2922 status = write16(state, IQM_AF_START_LOCK__A, 1);
2923 if (status < 0)
2924 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002925
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002926 *count = 0;
2927 status = read16(state, IQM_AF_PHASE0__A, &data);
2928 if (status < 0)
2929 goto error;
2930 if (data == 127)
2931 *count = *count + 1;
2932 status = read16(state, IQM_AF_PHASE1__A, &data);
2933 if (status < 0)
2934 goto error;
2935 if (data == 127)
2936 *count = *count + 1;
2937 status = read16(state, IQM_AF_PHASE2__A, &data);
2938 if (status < 0)
2939 goto error;
2940 if (data == 127)
2941 *count = *count + 1;
2942
2943error:
2944 if (status < 0)
2945 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002946 return status;
2947}
2948
2949static int ADCSynchronization(struct drxk_state *state)
2950{
2951 u16 count = 0;
2952 int status;
2953
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002954 dprintk(1, "\n");
2955
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002956 status = ADCSyncMeasurement(state, &count);
2957 if (status < 0)
2958 goto error;
2959
2960 if (count == 1) {
2961 /* Try sampling on a diffrent edge */
2962 u16 clkNeg = 0;
2963
2964 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2965 if (status < 0)
2966 goto error;
2967 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2968 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2969 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2970 clkNeg |=
2971 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2972 } else {
2973 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2974 clkNeg |=
2975 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2976 }
2977 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2978 if (status < 0)
2979 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002980 status = ADCSyncMeasurement(state, &count);
2981 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002982 goto error;
2983 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002984
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002985 if (count < 2)
2986 status = -EINVAL;
2987error:
2988 if (status < 0)
2989 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002990 return status;
2991}
2992
2993static int SetFrequencyShifter(struct drxk_state *state,
2994 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002995 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002996{
2997 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002998 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002999 u32 fmFrequencyShift = 0;
3000 bool tunerMirror = !state->m_bMirrorFreqSpect;
3001 u32 adcFreq;
3002 bool adcFlip;
3003 int status;
3004 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003005 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003006 u32 frequencyShift;
3007 bool imageToSelect;
3008
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003009 dprintk(1, "\n");
3010
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003011 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003012 Program frequency shifter
3013 No need to account for mirroring on RF
3014 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003015 if (isDTV) {
3016 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3017 (state->m_OperationMode == OM_QAM_ITU_C) ||
3018 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003019 selectPosImage = true;
3020 else
3021 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003022 }
3023 if (tunerMirror)
3024 /* tuner doesn't mirror */
3025 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003026 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003027 else
3028 /* tuner mirrors */
3029 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003030 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003031 if (ifFreqActual > samplingFrequency / 2) {
3032 /* adc mirrors */
3033 adcFreq = samplingFrequency - ifFreqActual;
3034 adcFlip = true;
3035 } else {
3036 /* adc doesn't mirror */
3037 adcFreq = ifFreqActual;
3038 adcFlip = false;
3039 }
3040
3041 frequencyShift = adcFreq;
3042 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003043 adcFlip ^ selectPosImage;
3044 state->m_IqmFsRateOfs =
3045 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003046
3047 if (imageToSelect)
3048 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3049
3050 /* Program frequency shifter with tuner offset compensation */
3051 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003052 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3053 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003054 if (status < 0)
3055 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003056 return status;
3057}
3058
3059static int InitAGC(struct drxk_state *state, bool isDTV)
3060{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003061 u16 ingainTgt = 0;
3062 u16 ingainTgtMin = 0;
3063 u16 ingainTgtMax = 0;
3064 u16 clpCyclen = 0;
3065 u16 clpSumMin = 0;
3066 u16 clpDirTo = 0;
3067 u16 snsSumMin = 0;
3068 u16 snsSumMax = 0;
3069 u16 clpSumMax = 0;
3070 u16 snsDirTo = 0;
3071 u16 kiInnergainMin = 0;
3072 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003073 u16 ifIaccuHiTgtMin = 0;
3074 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003075 u16 data = 0;
3076 u16 fastClpCtrlDelay = 0;
3077 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003078 int status = 0;
3079
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003080 dprintk(1, "\n");
3081
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003082 /* Common settings */
3083 snsSumMax = 1023;
3084 ifIaccuHiTgtMin = 2047;
3085 clpCyclen = 500;
3086 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003087
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003088 /* AGCInit() not available for DVBT; init done in microcode */
3089 if (!IsQAM(state)) {
3090 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3091 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003092 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003093
3094 /* FIXME: Analog TV AGC require different settings */
3095
3096 /* Standard specific settings */
3097 clpSumMin = 8;
3098 clpDirTo = (u16) -9;
3099 clpCtrlMode = 0;
3100 snsSumMin = 8;
3101 snsDirTo = (u16) -9;
3102 kiInnergainMin = (u16) -1030;
3103 ifIaccuHiTgtMax = 0x2380;
3104 ifIaccuHiTgt = 0x2380;
3105 ingainTgtMin = 0x0511;
3106 ingainTgt = 0x0511;
3107 ingainTgtMax = 5119;
3108 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3109
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003110 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3111 if (status < 0)
3112 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003113
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003114 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3115 if (status < 0)
3116 goto error;
3117 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3118 if (status < 0)
3119 goto error;
3120 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3121 if (status < 0)
3122 goto error;
3123 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3124 if (status < 0)
3125 goto error;
3126 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3127 if (status < 0)
3128 goto error;
3129 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3130 if (status < 0)
3131 goto error;
3132 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3133 if (status < 0)
3134 goto error;
3135 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3136 if (status < 0)
3137 goto error;
3138 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3139 if (status < 0)
3140 goto error;
3141 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3142 if (status < 0)
3143 goto error;
3144 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3145 if (status < 0)
3146 goto error;
3147 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3148 if (status < 0)
3149 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003150
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003151 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3152 if (status < 0)
3153 goto error;
3154 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3155 if (status < 0)
3156 goto error;
3157 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3158 if (status < 0)
3159 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003160
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003161 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3162 if (status < 0)
3163 goto error;
3164 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3165 if (status < 0)
3166 goto error;
3167 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3168 if (status < 0)
3169 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003170
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003171 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3172 if (status < 0)
3173 goto error;
3174 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3175 if (status < 0)
3176 goto error;
3177 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3178 if (status < 0)
3179 goto error;
3180 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3181 if (status < 0)
3182 goto error;
3183 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3184 if (status < 0)
3185 goto error;
3186 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3187 if (status < 0)
3188 goto error;
3189 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3190 if (status < 0)
3191 goto error;
3192 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3193 if (status < 0)
3194 goto error;
3195 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3196 if (status < 0)
3197 goto error;
3198 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3199 if (status < 0)
3200 goto error;
3201 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3202 if (status < 0)
3203 goto error;
3204 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3205 if (status < 0)
3206 goto error;
3207 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3208 if (status < 0)
3209 goto error;
3210 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3211 if (status < 0)
3212 goto error;
3213 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3214 if (status < 0)
3215 goto error;
3216 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3217 if (status < 0)
3218 goto error;
3219 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3220 if (status < 0)
3221 goto error;
3222 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3223 if (status < 0)
3224 goto error;
3225 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3226 if (status < 0)
3227 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003228
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003229 /* Initialize inner-loop KI gain factors */
3230 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3231 if (status < 0)
3232 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003233
3234 data = 0x0657;
3235 data &= ~SCU_RAM_AGC_KI_RF__M;
3236 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3237 data &= ~SCU_RAM_AGC_KI_IF__M;
3238 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3239
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003240 status = write16(state, SCU_RAM_AGC_KI__A, data);
3241error:
3242 if (status < 0)
3243 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003244 return status;
3245}
3246
Oliver Endrissebc7de22011-07-03 13:49:44 -03003247static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003248{
3249 int status;
3250
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003251 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003252 if (packetErr == NULL)
3253 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3254 else
3255 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3256 if (status < 0)
3257 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003258 return status;
3259}
3260
3261static int DVBTScCommand(struct drxk_state *state,
3262 u16 cmd, u16 subcmd,
3263 u16 param0, u16 param1, u16 param2,
3264 u16 param3, u16 param4)
3265{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003266 u16 curCmd = 0;
3267 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003268 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003269 u16 scExec = 0;
3270 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003271
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003272 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003273 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003274 if (scExec != 1) {
3275 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003276 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003277 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003278 if (status < 0)
3279 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003280
3281 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003282 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003283 do {
3284 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003285 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003286 retryCnt++;
3287 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003288 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3289 goto error;
3290
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003291 /* Write sub-command */
3292 switch (cmd) {
3293 /* All commands using sub-cmd */
3294 case OFDM_SC_RA_RAM_CMD_PROC_START:
3295 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3296 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003297 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3298 if (status < 0)
3299 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003300 break;
3301 default:
3302 /* Do nothing */
3303 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003304 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003305
3306 /* Write needed parameters and the command */
3307 switch (cmd) {
3308 /* All commands using 5 parameters */
3309 /* All commands using 4 parameters */
3310 /* All commands using 3 parameters */
3311 /* All commands using 2 parameters */
3312 case OFDM_SC_RA_RAM_CMD_PROC_START:
3313 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3314 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003315 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003316 /* All commands using 1 parameters */
3317 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3318 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003319 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003320 /* All commands using 0 parameters */
3321 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3322 case OFDM_SC_RA_RAM_CMD_NULL:
3323 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003324 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003325 break;
3326 default:
3327 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003328 status = -EINVAL;
3329 }
3330 if (status < 0)
3331 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003332
3333 /* Wait until sc is ready processing command */
3334 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003335 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003336 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003337 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003338 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003339 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003340 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3341 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003342
3343 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003344 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003345 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003346 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003347 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003348 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003349 if (status < 0)
3350 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003351
3352 /* Retreive results parameters from SC */
3353 switch (cmd) {
3354 /* All commands yielding 5 results */
3355 /* All commands yielding 4 results */
3356 /* All commands yielding 3 results */
3357 /* All commands yielding 2 results */
3358 /* All commands yielding 1 result */
3359 case OFDM_SC_RA_RAM_CMD_USER_IO:
3360 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003361 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003362 /* All commands yielding 0 results */
3363 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3364 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3365 case OFDM_SC_RA_RAM_CMD_PROC_START:
3366 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3367 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3368 case OFDM_SC_RA_RAM_CMD_NULL:
3369 break;
3370 default:
3371 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003372 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003373 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003374 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003375error:
3376 if (status < 0)
3377 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003378 return status;
3379}
3380
Oliver Endrissebc7de22011-07-03 13:49:44 -03003381static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003382{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003383 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003384 int status;
3385
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003386 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003387 status = CtrlPowerMode(state, &powerMode);
3388 if (status < 0)
3389 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003390 return status;
3391}
3392
Oliver Endrissebc7de22011-07-03 13:49:44 -03003393static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003394{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003395 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003396
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003397 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003398 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003399 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003400 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003401 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003402 if (status < 0)
3403 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003404 return status;
3405}
3406
3407#define DEFAULT_FR_THRES_8K 4000
3408static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3409{
3410
3411 int status;
3412
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003413 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003414 if (*enabled == true) {
3415 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003416 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003417 DEFAULT_FR_THRES_8K);
3418 } else {
3419 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003420 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003421 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003422 if (status < 0)
3423 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003424
3425 return status;
3426}
3427
3428static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3429 struct DRXKCfgDvbtEchoThres_t *echoThres)
3430{
3431 u16 data = 0;
3432 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003433
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003434 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003435 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3436 if (status < 0)
3437 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003438
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003439 switch (echoThres->fftMode) {
3440 case DRX_FFTMODE_2K:
3441 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3442 data |= ((echoThres->threshold <<
3443 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3444 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003445 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003446 case DRX_FFTMODE_8K:
3447 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3448 data |= ((echoThres->threshold <<
3449 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3450 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003451 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003452 default:
3453 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003454 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003455
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003456 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3457error:
3458 if (status < 0)
3459 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003460 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003461}
3462
3463static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003464 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003465{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003466 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003467
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003468 dprintk(1, "\n");
3469
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003470 switch (*speed) {
3471 case DRXK_DVBT_SQI_SPEED_FAST:
3472 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3473 case DRXK_DVBT_SQI_SPEED_SLOW:
3474 break;
3475 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003476 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003477 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003478 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003479 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003480error:
3481 if (status < 0)
3482 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003483 return status;
3484}
3485
3486/*============================================================================*/
3487
3488/**
3489* \brief Activate DVBT specific presets
3490* \param demod instance of demodulator.
3491* \return DRXStatus_t.
3492*
3493* Called in DVBTSetStandard
3494*
3495*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003496static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003497{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003498 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003499 bool setincenable = false;
3500 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003501
Oliver Endrissebc7de22011-07-03 13:49:44 -03003502 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3503 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003504
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003505 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003506 status = DVBTCtrlSetIncEnable(state, &setincenable);
3507 if (status < 0)
3508 goto error;
3509 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3510 if (status < 0)
3511 goto error;
3512 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3513 if (status < 0)
3514 goto error;
3515 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3516 if (status < 0)
3517 goto error;
3518 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3519error:
3520 if (status < 0)
3521 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003522 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003523}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003524
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003525/*============================================================================*/
3526
3527/**
3528* \brief Initialize channelswitch-independent settings for DVBT.
3529* \param demod instance of demodulator.
3530* \return DRXStatus_t.
3531*
3532* For ROM code channel filter taps are loaded from the bootloader. For microcode
3533* the DVB-T taps from the drxk_filters.h are used.
3534*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003535static int SetDVBTStandard(struct drxk_state *state,
3536 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003537{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003538 u16 cmdResult = 0;
3539 u16 data = 0;
3540 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003541
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003542 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003543
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003544 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003545 /* added antenna switch */
3546 SwitchAntennaToDVBT(state);
3547 /* send OFDM reset command */
3548 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003549 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003550 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003551
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003552 /* send OFDM setenv command */
3553 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3554 if (status < 0)
3555 goto error;
3556
3557 /* reset datapath for OFDM, processors first */
3558 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3559 if (status < 0)
3560 goto error;
3561 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3562 if (status < 0)
3563 goto error;
3564 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3565 if (status < 0)
3566 goto error;
3567
3568 /* IQM setup */
3569 /* synchronize on ofdstate->m_festart */
3570 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3571 if (status < 0)
3572 goto error;
3573 /* window size for clipping ADC detection */
3574 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3575 if (status < 0)
3576 goto error;
3577 /* window size for for sense pre-SAW detection */
3578 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3579 if (status < 0)
3580 goto error;
3581 /* sense threshold for sense pre-SAW detection */
3582 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3583 if (status < 0)
3584 goto error;
3585 status = SetIqmAf(state, true);
3586 if (status < 0)
3587 goto error;
3588
3589 status = write16(state, IQM_AF_AGC_RF__A, 0);
3590 if (status < 0)
3591 goto error;
3592
3593 /* Impulse noise cruncher setup */
3594 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3595 if (status < 0)
3596 goto error;
3597 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3598 if (status < 0)
3599 goto error;
3600 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3601 if (status < 0)
3602 goto error;
3603
3604 status = write16(state, IQM_RC_STRETCH__A, 16);
3605 if (status < 0)
3606 goto error;
3607 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3608 if (status < 0)
3609 goto error;
3610 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3611 if (status < 0)
3612 goto error;
3613 status = write16(state, IQM_CF_SCALE__A, 1600);
3614 if (status < 0)
3615 goto error;
3616 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3617 if (status < 0)
3618 goto error;
3619
3620 /* virtual clipping threshold for clipping ADC detection */
3621 status = write16(state, IQM_AF_CLP_TH__A, 448);
3622 if (status < 0)
3623 goto error;
3624 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3625 if (status < 0)
3626 goto error;
3627
3628 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3629 if (status < 0)
3630 goto error;
3631
3632 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3633 if (status < 0)
3634 goto error;
3635 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3636 if (status < 0)
3637 goto error;
3638 /* enable power measurement interrupt */
3639 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3640 if (status < 0)
3641 goto error;
3642 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3643 if (status < 0)
3644 goto error;
3645
3646 /* IQM will not be reset from here, sync ADC and update/init AGC */
3647 status = ADCSynchronization(state);
3648 if (status < 0)
3649 goto error;
3650 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3651 if (status < 0)
3652 goto error;
3653
3654 /* Halt SCU to enable safe non-atomic accesses */
3655 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3656 if (status < 0)
3657 goto error;
3658
3659 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3660 if (status < 0)
3661 goto error;
3662 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3663 if (status < 0)
3664 goto error;
3665
3666 /* Set Noise Estimation notch width and enable DC fix */
3667 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3668 if (status < 0)
3669 goto error;
3670 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3671 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3672 if (status < 0)
3673 goto error;
3674
3675 /* Activate SCU to enable SCU commands */
3676 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3677 if (status < 0)
3678 goto error;
3679
3680 if (!state->m_DRXK_A3_ROM_CODE) {
3681 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3682 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3683 if (status < 0)
3684 goto error;
3685 }
3686
3687 /* OFDM_SC setup */
3688#ifdef COMPILE_FOR_NONRT
3689 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3690 if (status < 0)
3691 goto error;
3692 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3693 if (status < 0)
3694 goto error;
3695#endif
3696
3697 /* FEC setup */
3698 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3699 if (status < 0)
3700 goto error;
3701
3702
3703#ifdef COMPILE_FOR_NONRT
3704 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3705 if (status < 0)
3706 goto error;
3707#else
3708 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3709 if (status < 0)
3710 goto error;
3711#endif
3712 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3713 if (status < 0)
3714 goto error;
3715
3716 /* Setup MPEG bus */
3717 status = MPEGTSDtoSetup(state, OM_DVBT);
3718 if (status < 0)
3719 goto error;
3720 /* Set DVBT Presets */
3721 status = DVBTActivatePresets(state);
3722 if (status < 0)
3723 goto error;
3724
3725error:
3726 if (status < 0)
3727 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003728 return status;
3729}
3730
3731/*============================================================================*/
3732/**
3733* \brief Start dvbt demodulating for channel.
3734* \param demod instance of demodulator.
3735* \return DRXStatus_t.
3736*/
3737static int DVBTStart(struct drxk_state *state)
3738{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003739 u16 param1;
3740 int status;
3741 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003742
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003743 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003744 /* Start correct processes to get in lock */
3745 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003746 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3747 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3748 if (status < 0)
3749 goto error;
3750 /* Start FEC OC */
3751 status = MPEGTSStart(state);
3752 if (status < 0)
3753 goto error;
3754 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3755 if (status < 0)
3756 goto error;
3757error:
3758 if (status < 0)
3759 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003760 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003761}
3762
3763
3764/*============================================================================*/
3765
3766/**
3767* \brief Set up dvbt demodulator for channel.
3768* \param demod instance of demodulator.
3769* \return DRXStatus_t.
3770* // original DVBTSetChannel()
3771*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003772static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3773 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003774{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003775 u16 cmdResult = 0;
3776 u16 transmissionParams = 0;
3777 u16 operationMode = 0;
3778 u32 iqmRcRateOfs = 0;
3779 u32 bandwidth = 0;
3780 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003781 int status;
3782
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003783 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003784
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003785 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3786 if (status < 0)
3787 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003788
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003789 /* Halt SCU to enable safe non-atomic accesses */
3790 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3791 if (status < 0)
3792 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003793
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003794 /* Stop processors */
3795 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3796 if (status < 0)
3797 goto error;
3798 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3799 if (status < 0)
3800 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003801
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003802 /* Mandatory fix, always stop CP, required to set spl offset back to
3803 hardware default (is set to 0 by ucode during pilot detection */
3804 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3805 if (status < 0)
3806 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003807
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003808 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003809
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003810 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003811 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003812 case TRANSMISSION_MODE_AUTO:
3813 default:
3814 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3815 /* fall through , try first guess DRX_FFTMODE_8K */
3816 case TRANSMISSION_MODE_8K:
3817 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003818 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003819 case TRANSMISSION_MODE_2K:
3820 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003821 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003822 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003823
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003824 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003825 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003826 default:
3827 case GUARD_INTERVAL_AUTO:
3828 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3829 /* fall through , try first guess DRX_GUARD_1DIV4 */
3830 case GUARD_INTERVAL_1_4:
3831 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003832 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003833 case GUARD_INTERVAL_1_32:
3834 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003835 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003836 case GUARD_INTERVAL_1_16:
3837 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003838 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003839 case GUARD_INTERVAL_1_8:
3840 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003841 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003842 }
3843
3844 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003845 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003846 case HIERARCHY_AUTO:
3847 case HIERARCHY_NONE:
3848 default:
3849 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3850 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3851 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3852 /* break; */
3853 case HIERARCHY_1:
3854 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3855 break;
3856 case HIERARCHY_2:
3857 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3858 break;
3859 case HIERARCHY_4:
3860 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3861 break;
3862 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003863
3864
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003865 /* modulation */
3866 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003867 case QAM_AUTO:
3868 default:
3869 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3870 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3871 case QAM_64:
3872 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3873 break;
3874 case QPSK:
3875 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3876 break;
3877 case QAM_16:
3878 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3879 break;
3880 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003881#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003882 /* No hierachical channels support in BDA */
3883 /* Priority (only for hierarchical channels) */
3884 switch (channel->priority) {
3885 case DRX_PRIORITY_LOW:
3886 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3887 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3888 OFDM_EC_SB_PRIOR_LO);
3889 break;
3890 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003891 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003892 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3893 OFDM_EC_SB_PRIOR_HI));
3894 break;
3895 case DRX_PRIORITY_UNKNOWN: /* fall through */
3896 default:
3897 status = -EINVAL;
3898 goto error;
3899 }
3900#else
3901 /* Set Priorty high */
3902 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3903 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3904 if (status < 0)
3905 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003906#endif
3907
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003908 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003909 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003910 case FEC_AUTO:
3911 default:
3912 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3913 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3914 case FEC_2_3:
3915 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3916 break;
3917 case FEC_1_2:
3918 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3919 break;
3920 case FEC_3_4:
3921 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3922 break;
3923 case FEC_5_6:
3924 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3925 break;
3926 case FEC_7_8:
3927 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3928 break;
3929 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003930
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003931 /* SAW filter selection: normaly not necesarry, but if wanted
3932 the application can select a SAW filter via the driver by using UIOs */
3933 /* First determine real bandwidth (Hz) */
3934 /* Also set delay for impulse noise cruncher */
3935 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3936 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3937 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003938 switch (state->props.bandwidth_hz) {
3939 case 0:
3940 state->props.bandwidth_hz = 8000000;
3941 /* fall though */
3942 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003943 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3944 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003945 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003946 goto error;
3947 /* cochannel protection for PAL 8 MHz */
3948 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3949 if (status < 0)
3950 goto error;
3951 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3952 if (status < 0)
3953 goto error;
3954 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3955 if (status < 0)
3956 goto error;
3957 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3958 if (status < 0)
3959 goto error;
3960 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003961 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003962 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3963 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3964 if (status < 0)
3965 goto error;
3966 /* cochannel protection for PAL 7 MHz */
3967 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3968 if (status < 0)
3969 goto error;
3970 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3971 if (status < 0)
3972 goto error;
3973 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3974 if (status < 0)
3975 goto error;
3976 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3977 if (status < 0)
3978 goto error;
3979 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003980 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003981 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3982 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3983 if (status < 0)
3984 goto error;
3985 /* cochannel protection for NTSC 6 MHz */
3986 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3987 if (status < 0)
3988 goto error;
3989 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3990 if (status < 0)
3991 goto error;
3992 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3993 if (status < 0)
3994 goto error;
3995 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3996 if (status < 0)
3997 goto error;
3998 break;
3999 default:
4000 status = -EINVAL;
4001 goto error;
4002 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004003
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004004 if (iqmRcRateOfs == 0) {
4005 /* Now compute IQM_RC_RATE_OFS
4006 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4007 =>
4008 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4009 */
4010 /* (SysFreq / BandWidth) * (2^28) */
4011 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4012 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4013 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4014 iqmRcRateOfs = Frac28a((u32)
4015 ((state->m_sysClockFreq *
4016 1000) / 3), bandwidth);
4017 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4018 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4019 iqmRcRateOfs += 0x80L;
4020 iqmRcRateOfs = iqmRcRateOfs >> 7;
4021 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4022 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4023 }
4024
4025 iqmRcRateOfs &=
4026 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4027 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4028 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4029 if (status < 0)
4030 goto error;
4031
4032 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004033
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004034#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004035 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4036 if (status < 0)
4037 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004038#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004039 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4040 if (status < 0)
4041 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004042
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004043 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004044
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004045 /* Activate SCU to enable SCU commands */
4046 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4047 if (status < 0)
4048 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004049
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004050 /* Enable SC after setting all other parameters */
4051 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4052 if (status < 0)
4053 goto error;
4054 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4055 if (status < 0)
4056 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004057
4058
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004059 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4060 if (status < 0)
4061 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004062
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004063 /* Write SC parameter registers, set all AUTO flags in operation mode */
4064 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4065 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4066 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4067 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4068 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4069 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4070 0, transmissionParams, param1, 0, 0, 0);
4071 if (status < 0)
4072 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004073
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004074 if (!state->m_DRXK_A3_ROM_CODE)
4075 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4076error:
4077 if (status < 0)
4078 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004079
4080 return status;
4081}
4082
4083
4084/*============================================================================*/
4085
4086/**
4087* \brief Retreive lock status .
4088* \param demod Pointer to demodulator instance.
4089* \param lockStat Pointer to lock status structure.
4090* \return DRXStatus_t.
4091*
4092*/
4093static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4094{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004095 int status;
4096 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4097 OFDM_SC_RA_RAM_LOCK_FEC__M);
4098 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4099 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004100
Oliver Endrissebc7de22011-07-03 13:49:44 -03004101 u16 ScRaRamLock = 0;
4102 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004103
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004104 dprintk(1, "\n");
4105
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004106 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004107 /* driver 0.9.0 */
4108 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004109 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004110 if (status < 0)
4111 goto end;
4112 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4113 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004114
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004115 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004116 if (status < 0)
4117 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004118
Oliver Endrissebc7de22011-07-03 13:49:44 -03004119 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4120 *pLockStatus = MPEG_LOCK;
4121 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4122 *pLockStatus = FEC_LOCK;
4123 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4124 *pLockStatus = DEMOD_LOCK;
4125 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4126 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004127end:
4128 if (status < 0)
4129 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004130
Oliver Endrissebc7de22011-07-03 13:49:44 -03004131 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004132}
4133
Oliver Endrissebc7de22011-07-03 13:49:44 -03004134static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004135{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004136 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004137 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004138
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004139 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004140 status = CtrlPowerMode(state, &powerMode);
4141 if (status < 0)
4142 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004143
Oliver Endrissebc7de22011-07-03 13:49:44 -03004144 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004145}
4146
4147
Oliver Endrissebc7de22011-07-03 13:49:44 -03004148/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004149static int PowerDownQAM(struct drxk_state *state)
4150{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004151 u16 data = 0;
4152 u16 cmdResult;
4153 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004154
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004155 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004156 status = read16(state, SCU_COMM_EXEC__A, &data);
4157 if (status < 0)
4158 goto error;
4159 if (data == SCU_COMM_EXEC_ACTIVE) {
4160 /*
4161 STOP demodulator
4162 QAM and HW blocks
4163 */
4164 /* stop all comstate->m_exec */
4165 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004166 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004167 goto error;
4168 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 -03004169 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004170 goto error;
4171 }
4172 /* powerdown AFE */
4173 status = SetIqmAf(state, false);
4174
4175error:
4176 if (status < 0)
4177 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004178
Oliver Endrissebc7de22011-07-03 13:49:44 -03004179 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004180}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004181
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004182/*============================================================================*/
4183
4184/**
4185* \brief Setup of the QAM Measurement intervals for signal quality
4186* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004187* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004188* \return DRXStatus_t.
4189*
4190* NOTE:
4191* Take into account that for certain settings the errorcounters can overflow.
4192* The implementation does not check this.
4193*
4194*/
4195static int SetQAMMeasurement(struct drxk_state *state,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004196 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004197 u32 symbolRate)
4198{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004199 u32 fecBitsDesired = 0; /* BER accounting period */
4200 u32 fecRsPeriodTotal = 0; /* Total period */
4201 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4202 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004203 int status = 0;
4204
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004205 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004206
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004207 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004208 /* fecBitsDesired = symbolRate [kHz] *
4209 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004210 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004211 SyncLoss (== 1) *
4212 ViterbiLoss (==1)
4213 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004214 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004215 case DRX_CONSTELLATION_QAM16:
4216 fecBitsDesired = 4 * symbolRate;
4217 break;
4218 case DRX_CONSTELLATION_QAM32:
4219 fecBitsDesired = 5 * symbolRate;
4220 break;
4221 case DRX_CONSTELLATION_QAM64:
4222 fecBitsDesired = 6 * symbolRate;
4223 break;
4224 case DRX_CONSTELLATION_QAM128:
4225 fecBitsDesired = 7 * symbolRate;
4226 break;
4227 case DRX_CONSTELLATION_QAM256:
4228 fecBitsDesired = 8 * symbolRate;
4229 break;
4230 default:
4231 status = -EINVAL;
4232 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004233 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004234 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004235
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004236 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4237 fecBitsDesired *= 500; /* meas. period [ms] */
4238
4239 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4240 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4241 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4242
4243 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4244 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4245 if (fecRsPrescale == 0) {
4246 /* Divide by zero (though impossible) */
4247 status = -EINVAL;
4248 if (status < 0)
4249 goto error;
4250 }
4251 fecRsPeriod =
4252 ((u16) fecRsPeriodTotal +
4253 (fecRsPrescale >> 1)) / fecRsPrescale;
4254
4255 /* write corresponding registers */
4256 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4257 if (status < 0)
4258 goto error;
4259 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4260 if (status < 0)
4261 goto error;
4262 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4263error:
4264 if (status < 0)
4265 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004266 return status;
4267}
4268
Oliver Endrissebc7de22011-07-03 13:49:44 -03004269static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004270{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004271 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004272
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004273 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004274 /* QAM Equalizer Setup */
4275 /* Equalizer */
4276 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4277 if (status < 0)
4278 goto error;
4279 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4280 if (status < 0)
4281 goto error;
4282 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4283 if (status < 0)
4284 goto error;
4285 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4286 if (status < 0)
4287 goto error;
4288 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4289 if (status < 0)
4290 goto error;
4291 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4292 if (status < 0)
4293 goto error;
4294 /* Decision Feedback Equalizer */
4295 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4296 if (status < 0)
4297 goto error;
4298 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4299 if (status < 0)
4300 goto error;
4301 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4302 if (status < 0)
4303 goto error;
4304 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4305 if (status < 0)
4306 goto error;
4307 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4308 if (status < 0)
4309 goto error;
4310 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4311 if (status < 0)
4312 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004313
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004314 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4315 if (status < 0)
4316 goto error;
4317 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4318 if (status < 0)
4319 goto error;
4320 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4321 if (status < 0)
4322 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004323
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004324 /* QAM Slicer Settings */
4325 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4326 if (status < 0)
4327 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004328
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004329 /* QAM Loop Controller Coeficients */
4330 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4331 if (status < 0)
4332 goto error;
4333 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4334 if (status < 0)
4335 goto error;
4336 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4337 if (status < 0)
4338 goto error;
4339 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4340 if (status < 0)
4341 goto error;
4342 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4343 if (status < 0)
4344 goto error;
4345 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4346 if (status < 0)
4347 goto error;
4348 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4349 if (status < 0)
4350 goto error;
4351 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4352 if (status < 0)
4353 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004354
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004355 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4356 if (status < 0)
4357 goto error;
4358 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4359 if (status < 0)
4360 goto error;
4361 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4362 if (status < 0)
4363 goto error;
4364 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4365 if (status < 0)
4366 goto error;
4367 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4368 if (status < 0)
4369 goto error;
4370 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4371 if (status < 0)
4372 goto error;
4373 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4374 if (status < 0)
4375 goto error;
4376 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4377 if (status < 0)
4378 goto error;
4379 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4380 if (status < 0)
4381 goto error;
4382 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4383 if (status < 0)
4384 goto error;
4385 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4386 if (status < 0)
4387 goto error;
4388 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4389 if (status < 0)
4390 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004391
4392
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004393 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004394
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004395 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4396 if (status < 0)
4397 goto error;
4398 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4399 if (status < 0)
4400 goto error;
4401 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4402 if (status < 0)
4403 goto error;
4404 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4405 if (status < 0)
4406 goto error;
4407 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4408 if (status < 0)
4409 goto error;
4410 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4411 if (status < 0)
4412 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004413
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004414 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4415 if (status < 0)
4416 goto error;
4417 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4418 if (status < 0)
4419 goto error;
4420 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4421 if (status < 0)
4422 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004423
4424
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004425 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004426
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004427 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4428 if (status < 0)
4429 goto error;
4430 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4431 if (status < 0)
4432 goto error;
4433 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4434 if (status < 0)
4435 goto error;
4436 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4437 if (status < 0)
4438 goto error;
4439 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4440 if (status < 0)
4441 goto error;
4442 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4443 if (status < 0)
4444 goto error;
4445 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4446 if (status < 0)
4447 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004448
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004449error:
4450 if (status < 0)
4451 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004452 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004453}
4454
4455/*============================================================================*/
4456
4457/**
4458* \brief QAM32 specific setup
4459* \param demod instance of demod.
4460* \return DRXStatus_t.
4461*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004462static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004463{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004464 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004465
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004466 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004467
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004468 /* QAM Equalizer Setup */
4469 /* Equalizer */
4470 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4471 if (status < 0)
4472 goto error;
4473 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4474 if (status < 0)
4475 goto error;
4476 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4477 if (status < 0)
4478 goto error;
4479 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4480 if (status < 0)
4481 goto error;
4482 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4483 if (status < 0)
4484 goto error;
4485 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4486 if (status < 0)
4487 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004488
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004489 /* Decision Feedback Equalizer */
4490 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4491 if (status < 0)
4492 goto error;
4493 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4494 if (status < 0)
4495 goto error;
4496 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4497 if (status < 0)
4498 goto error;
4499 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4500 if (status < 0)
4501 goto error;
4502 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4503 if (status < 0)
4504 goto error;
4505 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4506 if (status < 0)
4507 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004508
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004509 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4510 if (status < 0)
4511 goto error;
4512 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4513 if (status < 0)
4514 goto error;
4515 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4516 if (status < 0)
4517 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004518
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004519 /* QAM Slicer Settings */
4520
4521 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4522 if (status < 0)
4523 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004524
4525
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004526 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004527
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004528 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4529 if (status < 0)
4530 goto error;
4531 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4532 if (status < 0)
4533 goto error;
4534 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4535 if (status < 0)
4536 goto error;
4537 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4538 if (status < 0)
4539 goto error;
4540 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4541 if (status < 0)
4542 goto error;
4543 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4544 if (status < 0)
4545 goto error;
4546 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4547 if (status < 0)
4548 goto error;
4549 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4550 if (status < 0)
4551 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004552
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004553 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4554 if (status < 0)
4555 goto error;
4556 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4557 if (status < 0)
4558 goto error;
4559 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4560 if (status < 0)
4561 goto error;
4562 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4563 if (status < 0)
4564 goto error;
4565 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4566 if (status < 0)
4567 goto error;
4568 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4569 if (status < 0)
4570 goto error;
4571 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4572 if (status < 0)
4573 goto error;
4574 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4575 if (status < 0)
4576 goto error;
4577 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4578 if (status < 0)
4579 goto error;
4580 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4581 if (status < 0)
4582 goto error;
4583 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4584 if (status < 0)
4585 goto error;
4586 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4587 if (status < 0)
4588 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004589
4590
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004591 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004592
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004593 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4594 if (status < 0)
4595 goto error;
4596 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4597 if (status < 0)
4598 goto error;
4599 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4600 if (status < 0)
4601 goto error;
4602 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4603 if (status < 0)
4604 goto error;
4605 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4606 if (status < 0)
4607 goto error;
4608 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4609 if (status < 0)
4610 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004611
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004612 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4613 if (status < 0)
4614 goto error;
4615 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4616 if (status < 0)
4617 goto error;
4618 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4619 if (status < 0)
4620 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004621
4622
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004623 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004624
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004625 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4626 if (status < 0)
4627 goto error;
4628 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4629 if (status < 0)
4630 goto error;
4631 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4632 if (status < 0)
4633 goto error;
4634 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4635 if (status < 0)
4636 goto error;
4637 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4638 if (status < 0)
4639 goto error;
4640 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4641 if (status < 0)
4642 goto error;
4643 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4644error:
4645 if (status < 0)
4646 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004647 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004648}
4649
4650/*============================================================================*/
4651
4652/**
4653* \brief QAM64 specific setup
4654* \param demod instance of demod.
4655* \return DRXStatus_t.
4656*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004657static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004658{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004659 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004660
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004661 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004662 /* QAM Equalizer Setup */
4663 /* Equalizer */
4664 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4665 if (status < 0)
4666 goto error;
4667 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4668 if (status < 0)
4669 goto error;
4670 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4671 if (status < 0)
4672 goto error;
4673 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4674 if (status < 0)
4675 goto error;
4676 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4677 if (status < 0)
4678 goto error;
4679 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4680 if (status < 0)
4681 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004682
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004683 /* Decision Feedback Equalizer */
4684 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4685 if (status < 0)
4686 goto error;
4687 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4688 if (status < 0)
4689 goto error;
4690 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4691 if (status < 0)
4692 goto error;
4693 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4694 if (status < 0)
4695 goto error;
4696 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4697 if (status < 0)
4698 goto error;
4699 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4700 if (status < 0)
4701 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004702
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004703 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4704 if (status < 0)
4705 goto error;
4706 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4707 if (status < 0)
4708 goto error;
4709 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4710 if (status < 0)
4711 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004712
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004713 /* QAM Slicer Settings */
4714 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4715 if (status < 0)
4716 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004717
4718
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004719 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004720
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004721 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4722 if (status < 0)
4723 goto error;
4724 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4725 if (status < 0)
4726 goto error;
4727 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4728 if (status < 0)
4729 goto error;
4730 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4731 if (status < 0)
4732 goto error;
4733 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4734 if (status < 0)
4735 goto error;
4736 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4737 if (status < 0)
4738 goto error;
4739 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4740 if (status < 0)
4741 goto error;
4742 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4743 if (status < 0)
4744 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004745
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004746 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4747 if (status < 0)
4748 goto error;
4749 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4750 if (status < 0)
4751 goto error;
4752 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4753 if (status < 0)
4754 goto error;
4755 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4756 if (status < 0)
4757 goto error;
4758 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4759 if (status < 0)
4760 goto error;
4761 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4762 if (status < 0)
4763 goto error;
4764 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4765 if (status < 0)
4766 goto error;
4767 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4768 if (status < 0)
4769 goto error;
4770 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4771 if (status < 0)
4772 goto error;
4773 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4774 if (status < 0)
4775 goto error;
4776 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4777 if (status < 0)
4778 goto error;
4779 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4780 if (status < 0)
4781 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004782
4783
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004784 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004785
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004786 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4787 if (status < 0)
4788 goto error;
4789 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4790 if (status < 0)
4791 goto error;
4792 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4793 if (status < 0)
4794 goto error;
4795 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4796 if (status < 0)
4797 goto error;
4798 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4799 if (status < 0)
4800 goto error;
4801 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4802 if (status < 0)
4803 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004804
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004805 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4806 if (status < 0)
4807 goto error;
4808 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4809 if (status < 0)
4810 goto error;
4811 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4812 if (status < 0)
4813 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004814
4815
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004816 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004817
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004818 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4819 if (status < 0)
4820 goto error;
4821 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4822 if (status < 0)
4823 goto error;
4824 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4825 if (status < 0)
4826 goto error;
4827 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4828 if (status < 0)
4829 goto error;
4830 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4831 if (status < 0)
4832 goto error;
4833 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4834 if (status < 0)
4835 goto error;
4836 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4837error:
4838 if (status < 0)
4839 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004840
Oliver Endrissebc7de22011-07-03 13:49:44 -03004841 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004842}
4843
4844/*============================================================================*/
4845
4846/**
4847* \brief QAM128 specific setup
4848* \param demod: instance of demod.
4849* \return DRXStatus_t.
4850*/
4851static int SetQAM128(struct drxk_state *state)
4852{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004853 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004854
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004855 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004856 /* QAM Equalizer Setup */
4857 /* Equalizer */
4858 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4859 if (status < 0)
4860 goto error;
4861 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4862 if (status < 0)
4863 goto error;
4864 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4865 if (status < 0)
4866 goto error;
4867 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4868 if (status < 0)
4869 goto error;
4870 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4871 if (status < 0)
4872 goto error;
4873 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4874 if (status < 0)
4875 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004876
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004877 /* Decision Feedback Equalizer */
4878 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4879 if (status < 0)
4880 goto error;
4881 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4882 if (status < 0)
4883 goto error;
4884 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4885 if (status < 0)
4886 goto error;
4887 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4888 if (status < 0)
4889 goto error;
4890 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4891 if (status < 0)
4892 goto error;
4893 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4894 if (status < 0)
4895 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004896
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004897 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4898 if (status < 0)
4899 goto error;
4900 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4901 if (status < 0)
4902 goto error;
4903 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4904 if (status < 0)
4905 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004906
4907
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004908 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004909
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004910 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4911 if (status < 0)
4912 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004913
4914
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004915 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004916
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004917 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4918 if (status < 0)
4919 goto error;
4920 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4921 if (status < 0)
4922 goto error;
4923 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4924 if (status < 0)
4925 goto error;
4926 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4927 if (status < 0)
4928 goto error;
4929 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4930 if (status < 0)
4931 goto error;
4932 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4933 if (status < 0)
4934 goto error;
4935 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4936 if (status < 0)
4937 goto error;
4938 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4939 if (status < 0)
4940 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004941
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004942 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4943 if (status < 0)
4944 goto error;
4945 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4946 if (status < 0)
4947 goto error;
4948 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4949 if (status < 0)
4950 goto error;
4951 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4952 if (status < 0)
4953 goto error;
4954 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4955 if (status < 0)
4956 goto error;
4957 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4958 if (status < 0)
4959 goto error;
4960 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4961 if (status < 0)
4962 goto error;
4963 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4964 if (status < 0)
4965 goto error;
4966 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4967 if (status < 0)
4968 goto error;
4969 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4970 if (status < 0)
4971 goto error;
4972 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4973 if (status < 0)
4974 goto error;
4975 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4976 if (status < 0)
4977 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004978
4979
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004980 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004981
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004982 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4983 if (status < 0)
4984 goto error;
4985 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4986 if (status < 0)
4987 goto error;
4988 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4989 if (status < 0)
4990 goto error;
4991 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4992 if (status < 0)
4993 goto error;
4994 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4995 if (status < 0)
4996 goto error;
4997 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4998 if (status < 0)
4999 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005000
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005001 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5002 if (status < 0)
5003 goto error;
5004 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5005 if (status < 0)
5006 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005007
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005008 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5009 if (status < 0)
5010 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005011
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005012 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005013
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005014 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5015 if (status < 0)
5016 goto error;
5017 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5018 if (status < 0)
5019 goto error;
5020 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5021 if (status < 0)
5022 goto error;
5023 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5024 if (status < 0)
5025 goto error;
5026 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5027 if (status < 0)
5028 goto error;
5029 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5030 if (status < 0)
5031 goto error;
5032 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5033error:
5034 if (status < 0)
5035 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005036
Oliver Endrissebc7de22011-07-03 13:49:44 -03005037 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005038}
5039
5040/*============================================================================*/
5041
5042/**
5043* \brief QAM256 specific setup
5044* \param demod: instance of demod.
5045* \return DRXStatus_t.
5046*/
5047static int SetQAM256(struct drxk_state *state)
5048{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005049 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005050
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005051 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005052 /* QAM Equalizer Setup */
5053 /* Equalizer */
5054 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5055 if (status < 0)
5056 goto error;
5057 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5058 if (status < 0)
5059 goto error;
5060 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5061 if (status < 0)
5062 goto error;
5063 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5064 if (status < 0)
5065 goto error;
5066 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5067 if (status < 0)
5068 goto error;
5069 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5070 if (status < 0)
5071 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005072
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005073 /* Decision Feedback Equalizer */
5074 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5075 if (status < 0)
5076 goto error;
5077 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5078 if (status < 0)
5079 goto error;
5080 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5081 if (status < 0)
5082 goto error;
5083 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5084 if (status < 0)
5085 goto error;
5086 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5087 if (status < 0)
5088 goto error;
5089 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5090 if (status < 0)
5091 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005092
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005093 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5094 if (status < 0)
5095 goto error;
5096 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5097 if (status < 0)
5098 goto error;
5099 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5100 if (status < 0)
5101 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005102
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005103 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005104
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005105 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5106 if (status < 0)
5107 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005108
5109
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005110 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005111
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005112 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5113 if (status < 0)
5114 goto error;
5115 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5116 if (status < 0)
5117 goto error;
5118 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5119 if (status < 0)
5120 goto error;
5121 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5122 if (status < 0)
5123 goto error;
5124 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5125 if (status < 0)
5126 goto error;
5127 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5128 if (status < 0)
5129 goto error;
5130 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5131 if (status < 0)
5132 goto error;
5133 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5134 if (status < 0)
5135 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005136
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005137 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5138 if (status < 0)
5139 goto error;
5140 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5141 if (status < 0)
5142 goto error;
5143 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5144 if (status < 0)
5145 goto error;
5146 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5147 if (status < 0)
5148 goto error;
5149 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5150 if (status < 0)
5151 goto error;
5152 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5153 if (status < 0)
5154 goto error;
5155 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5156 if (status < 0)
5157 goto error;
5158 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5159 if (status < 0)
5160 goto error;
5161 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5162 if (status < 0)
5163 goto error;
5164 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5165 if (status < 0)
5166 goto error;
5167 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5168 if (status < 0)
5169 goto error;
5170 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5171 if (status < 0)
5172 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005173
5174
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005175 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005176
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005177 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5178 if (status < 0)
5179 goto error;
5180 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5181 if (status < 0)
5182 goto error;
5183 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5184 if (status < 0)
5185 goto error;
5186 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5187 if (status < 0)
5188 goto error;
5189 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5190 if (status < 0)
5191 goto error;
5192 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5193 if (status < 0)
5194 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005195
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005196 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5197 if (status < 0)
5198 goto error;
5199 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5200 if (status < 0)
5201 goto error;
5202 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5203 if (status < 0)
5204 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005205
5206
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005207 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005208
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005209 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5210 if (status < 0)
5211 goto error;
5212 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5213 if (status < 0)
5214 goto error;
5215 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5216 if (status < 0)
5217 goto error;
5218 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5219 if (status < 0)
5220 goto error;
5221 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5222 if (status < 0)
5223 goto error;
5224 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5225 if (status < 0)
5226 goto error;
5227 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5228error:
5229 if (status < 0)
5230 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005231 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005232}
5233
5234
5235/*============================================================================*/
5236/**
5237* \brief Reset QAM block.
5238* \param demod: instance of demod.
5239* \param channel: pointer to channel data.
5240* \return DRXStatus_t.
5241*/
5242static int QAMResetQAM(struct drxk_state *state)
5243{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005244 int status;
5245 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005246
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005247 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005248 /* Stop QAM comstate->m_exec */
5249 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5250 if (status < 0)
5251 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005252
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005253 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5254error:
5255 if (status < 0)
5256 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005257 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005258}
5259
5260/*============================================================================*/
5261
5262/**
5263* \brief Set QAM symbolrate.
5264* \param demod: instance of demod.
5265* \param channel: pointer to channel data.
5266* \return DRXStatus_t.
5267*/
5268static int QAMSetSymbolrate(struct drxk_state *state)
5269{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005270 u32 adcFrequency = 0;
5271 u32 symbFreq = 0;
5272 u32 iqmRcRate = 0;
5273 u16 ratesel = 0;
5274 u32 lcSymbRate = 0;
5275 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005276
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005277 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005278 /* Select & calculate correct IQM rate */
5279 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5280 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005281 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5282 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005283 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005284 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005285 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005286 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005287 ratesel = 1;
5288 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5289 if (status < 0)
5290 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005291
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005292 /*
5293 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5294 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005295 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005296 if (symbFreq == 0) {
5297 /* Divide by zero */
5298 status = -EINVAL;
5299 goto error;
5300 }
5301 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5302 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5303 (1 << 23);
5304 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5305 if (status < 0)
5306 goto error;
5307 state->m_iqmRcRate = iqmRcRate;
5308 /*
5309 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5310 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005311 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005312 if (adcFrequency == 0) {
5313 /* Divide by zero */
5314 status = -EINVAL;
5315 goto error;
5316 }
5317 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5318 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5319 16);
5320 if (lcSymbRate > 511)
5321 lcSymbRate = 511;
5322 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005323
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005324error:
5325 if (status < 0)
5326 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005327 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005328}
5329
5330/*============================================================================*/
5331
5332/**
5333* \brief Get QAM lock status.
5334* \param demod: instance of demod.
5335* \param channel: pointer to channel data.
5336* \return DRXStatus_t.
5337*/
5338
5339static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5340{
5341 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005342 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005343
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005344 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005345 *pLockStatus = NOT_LOCKED;
5346 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005347 SCU_RAM_COMMAND_STANDARD_QAM |
5348 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5349 Result);
5350 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005351 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005352
5353 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005354 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005355 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005356 /* 0x4000 DEMOD LOCKED */
5357 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005358 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005359 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5360 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005361 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005362 /* 0xC000 NEVER LOCKED */
5363 /* (system will never be able to lock to the signal) */
5364 /* TODO: check this, intermediate & standard specific lock states are not
5365 taken into account here */
5366 *pLockStatus = NEVER_LOCK;
5367 }
5368 return status;
5369}
5370
5371#define QAM_MIRROR__M 0x03
5372#define QAM_MIRROR_NORMAL 0x00
5373#define QAM_MIRRORED 0x01
5374#define QAM_MIRROR_AUTO_ON 0x02
5375#define QAM_LOCKRANGE__M 0x10
5376#define QAM_LOCKRANGE_NORMAL 0x10
5377
Oliver Endrissebc7de22011-07-03 13:49:44 -03005378static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5379 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005380{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005381 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005382 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5383 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005384
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005385 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005386 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005387 * STEP 1: reset demodulator
5388 * resets FEC DI and FEC RS
5389 * resets QAM block
5390 * resets SCU variables
5391 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005392 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005393 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005394 goto error;
5395 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5396 if (status < 0)
5397 goto error;
5398 status = QAMResetQAM(state);
5399 if (status < 0)
5400 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005401
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005402 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005403 * STEP 2: configure demodulator
5404 * -set params; resets IQM,QAM,FEC HW; initializes some
5405 * SCU variables
5406 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005407 status = QAMSetSymbolrate(state);
5408 if (status < 0)
5409 goto error;
5410
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005411 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005412 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005413 case QAM_256:
5414 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5415 break;
5416 case QAM_AUTO:
5417 case QAM_64:
5418 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5419 break;
5420 case QAM_16:
5421 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5422 break;
5423 case QAM_32:
5424 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5425 break;
5426 case QAM_128:
5427 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5428 break;
5429 default:
5430 status = -EINVAL;
5431 break;
5432 }
5433 if (status < 0)
5434 goto error;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005435 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005436 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005437 if (state->m_OperationMode == OM_QAM_ITU_C)
5438 setParamParameters[2] = QAM_TOP_ANNEX_C;
5439 else
5440 setParamParameters[2] = QAM_TOP_ANNEX_A;
5441 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5442 /* Env parameters */
5443 /* check for LOCKRANGE Extented */
5444 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005445
5446 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 -03005447 if (status < 0) {
5448 /* Fall-back to the simpler call */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005449 if (state->m_OperationMode == OM_QAM_ITU_C)
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005450 setParamParameters[0] = QAM_TOP_ANNEX_C;
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005451 else
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005452 setParamParameters[0] = QAM_TOP_ANNEX_A;
5453 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult);
5454 if (status < 0)
5455 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005456
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005457 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005458 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005459 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
5460 }
5461 if (status < 0)
5462 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005463
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005464 /*
5465 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005466 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005467 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005468#if 0
5469 status = SetFrequency(channel, tunerFreqOffset));
5470 if (status < 0)
5471 goto error;
5472#endif
5473 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5474 if (status < 0)
5475 goto error;
5476
5477 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005478 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005479 if (status < 0)
5480 goto error;
5481
5482 /* Reset default values */
5483 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5484 if (status < 0)
5485 goto error;
5486 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5487 if (status < 0)
5488 goto error;
5489
5490 /* Reset default LC values */
5491 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5492 if (status < 0)
5493 goto error;
5494 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5495 if (status < 0)
5496 goto error;
5497 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5498 if (status < 0)
5499 goto error;
5500 status = write16(state, QAM_LC_MODE__A, 7);
5501 if (status < 0)
5502 goto error;
5503
5504 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5505 if (status < 0)
5506 goto error;
5507 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5508 if (status < 0)
5509 goto error;
5510 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5511 if (status < 0)
5512 goto error;
5513 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5514 if (status < 0)
5515 goto error;
5516 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5517 if (status < 0)
5518 goto error;
5519 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5520 if (status < 0)
5521 goto error;
5522 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5523 if (status < 0)
5524 goto error;
5525 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5526 if (status < 0)
5527 goto error;
5528 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5529 if (status < 0)
5530 goto error;
5531 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5532 if (status < 0)
5533 goto error;
5534 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5535 if (status < 0)
5536 goto error;
5537 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5538 if (status < 0)
5539 goto error;
5540 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5541 if (status < 0)
5542 goto error;
5543 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5544 if (status < 0)
5545 goto error;
5546 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5547 if (status < 0)
5548 goto error;
5549
5550 /* Mirroring, QAM-block starting point not inverted */
5551 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5552 if (status < 0)
5553 goto error;
5554
5555 /* Halt SCU to enable safe non-atomic accesses */
5556 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5557 if (status < 0)
5558 goto error;
5559
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005560 /* STEP 4: modulation specific setup */
5561 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005562 case QAM_16:
5563 status = SetQAM16(state);
5564 break;
5565 case QAM_32:
5566 status = SetQAM32(state);
5567 break;
5568 case QAM_AUTO:
5569 case QAM_64:
5570 status = SetQAM64(state);
5571 break;
5572 case QAM_128:
5573 status = SetQAM128(state);
5574 break;
5575 case QAM_256:
5576 status = SetQAM256(state);
5577 break;
5578 default:
5579 status = -EINVAL;
5580 break;
5581 }
5582 if (status < 0)
5583 goto error;
5584
5585 /* Activate SCU to enable SCU commands */
5586 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5587 if (status < 0)
5588 goto error;
5589
5590 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005591 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005592 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5593 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5594 if (status < 0)
5595 goto error;
5596
5597 /* Start processes */
5598 status = MPEGTSStart(state);
5599 if (status < 0)
5600 goto error;
5601 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5602 if (status < 0)
5603 goto error;
5604 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5605 if (status < 0)
5606 goto error;
5607 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5608 if (status < 0)
5609 goto error;
5610
5611 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5612 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5613 if (status < 0)
5614 goto error;
5615
5616 /* update global DRXK data container */
5617/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5618
5619error:
5620 if (status < 0)
5621 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005622 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005623}
5624
Oliver Endrissebc7de22011-07-03 13:49:44 -03005625static int SetQAMStandard(struct drxk_state *state,
5626 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005627{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005628 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005629#ifdef DRXK_QAM_TAPS
5630#define DRXK_QAMA_TAPS_SELECT
5631#include "drxk_filters.h"
5632#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005633#endif
5634
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005635 dprintk(1, "\n");
5636
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005637 /* added antenna switch */
5638 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005639
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005640 /* Ensure correct power-up mode */
5641 status = PowerUpQAM(state);
5642 if (status < 0)
5643 goto error;
5644 /* Reset QAM block */
5645 status = QAMResetQAM(state);
5646 if (status < 0)
5647 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005648
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005649 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005650
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005651 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5652 if (status < 0)
5653 goto error;
5654 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5655 if (status < 0)
5656 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005657
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005658 /* Upload IQM Channel Filter settings by
5659 boot loader from ROM table */
5660 switch (oMode) {
5661 case OM_QAM_ITU_A:
5662 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5663 break;
5664 case OM_QAM_ITU_C:
5665 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 -03005666 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005667 goto error;
5668 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5669 break;
5670 default:
5671 status = -EINVAL;
5672 }
5673 if (status < 0)
5674 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005675
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005676 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5677 if (status < 0)
5678 goto error;
5679 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5680 if (status < 0)
5681 goto error;
5682 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5683 if (status < 0)
5684 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005685
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005686 status = write16(state, IQM_RC_STRETCH__A, 21);
5687 if (status < 0)
5688 goto error;
5689 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5690 if (status < 0)
5691 goto error;
5692 status = write16(state, IQM_AF_CLP_TH__A, 448);
5693 if (status < 0)
5694 goto error;
5695 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5696 if (status < 0)
5697 goto error;
5698 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5699 if (status < 0)
5700 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005701
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005702 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5703 if (status < 0)
5704 goto error;
5705 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5706 if (status < 0)
5707 goto error;
5708 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5709 if (status < 0)
5710 goto error;
5711 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5712 if (status < 0)
5713 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005714
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005715 /* IQM Impulse Noise Processing Unit */
5716 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5717 if (status < 0)
5718 goto error;
5719 status = write16(state, IQM_CF_DATATH__A, 1000);
5720 if (status < 0)
5721 goto error;
5722 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5723 if (status < 0)
5724 goto error;
5725 status = write16(state, IQM_CF_DET_LCT__A, 0);
5726 if (status < 0)
5727 goto error;
5728 status = write16(state, IQM_CF_WND_LEN__A, 1);
5729 if (status < 0)
5730 goto error;
5731 status = write16(state, IQM_CF_PKDTH__A, 1);
5732 if (status < 0)
5733 goto error;
5734 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5735 if (status < 0)
5736 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005737
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005738 /* turn on IQMAF. Must be done before setAgc**() */
5739 status = SetIqmAf(state, true);
5740 if (status < 0)
5741 goto error;
5742 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5743 if (status < 0)
5744 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005745
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005746 /* IQM will not be reset from here, sync ADC and update/init AGC */
5747 status = ADCSynchronization(state);
5748 if (status < 0)
5749 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005750
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005751 /* Set the FSM step period */
5752 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5753 if (status < 0)
5754 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005755
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005756 /* Halt SCU to enable safe non-atomic accesses */
5757 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5758 if (status < 0)
5759 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005760
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005761 /* No more resets of the IQM, current standard correctly set =>
5762 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005763
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005764 status = InitAGC(state, true);
5765 if (status < 0)
5766 goto error;
5767 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5768 if (status < 0)
5769 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005770
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005771 /* Configure AGC's */
5772 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5773 if (status < 0)
5774 goto error;
5775 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5776 if (status < 0)
5777 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005778
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005779 /* Activate SCU to enable SCU commands */
5780 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5781error:
5782 if (status < 0)
5783 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005784 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005785}
5786
5787static int WriteGPIO(struct drxk_state *state)
5788{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005789 int status;
5790 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005791
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005792 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005793 /* stop lock indicator process */
5794 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5795 if (status < 0)
5796 goto error;
5797
5798 /* Write magic word to enable pdr reg write */
5799 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5800 if (status < 0)
5801 goto error;
5802
5803 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005804 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5805 /* write to io pad configuration register - output mode */
5806 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5807 if (status < 0)
5808 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005809
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005810 /* use corresponding bit in io data output registar */
5811 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5812 if (status < 0)
5813 goto error;
5814 if ((state->m_GPIO & 0x0001) == 0)
5815 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5816 else
5817 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5818 /* write back to io data output register */
5819 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5820 if (status < 0)
5821 goto error;
5822 }
5823 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5824 /* write to io pad configuration register - output mode */
5825 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5826 if (status < 0)
5827 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005828
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005829 /* use corresponding bit in io data output registar */
5830 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5831 if (status < 0)
5832 goto error;
5833 if ((state->m_GPIO & 0x0002) == 0)
5834 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5835 else
5836 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5837 /* write back to io data output register */
5838 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5839 if (status < 0)
5840 goto error;
5841 }
5842 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5843 /* write to io pad configuration register - output mode */
5844 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5845 if (status < 0)
5846 goto error;
5847
5848 /* use corresponding bit in io data output registar */
5849 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5850 if (status < 0)
5851 goto error;
5852 if ((state->m_GPIO & 0x0004) == 0)
5853 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5854 else
5855 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5856 /* write back to io data output register */
5857 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5858 if (status < 0)
5859 goto error;
5860 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005861 }
5862 /* Write magic word to disable pdr reg write */
5863 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5864error:
5865 if (status < 0)
5866 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005867 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005868}
5869
5870static int SwitchAntennaToQAM(struct drxk_state *state)
5871{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005872 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005873 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005874
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005875 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005876
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005877 if (!state->antenna_gpio)
5878 return 0;
5879
5880 gpio_state = state->m_GPIO & state->antenna_gpio;
5881
5882 if (state->antenna_dvbt ^ gpio_state) {
5883 /* Antenna is on DVB-T mode. Switch */
5884 if (state->antenna_dvbt)
5885 state->m_GPIO &= ~state->antenna_gpio;
5886 else
5887 state->m_GPIO |= state->antenna_gpio;
5888 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005889 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005890 if (status < 0)
5891 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005892 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005893}
5894
5895static int SwitchAntennaToDVBT(struct drxk_state *state)
5896{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005897 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005898 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005899
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005900 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005901
5902 if (!state->antenna_gpio)
5903 return 0;
5904
5905 gpio_state = state->m_GPIO & state->antenna_gpio;
5906
5907 if (!(state->antenna_dvbt ^ gpio_state)) {
5908 /* Antenna is on DVB-C mode. Switch */
5909 if (state->antenna_dvbt)
5910 state->m_GPIO |= state->antenna_gpio;
5911 else
5912 state->m_GPIO &= ~state->antenna_gpio;
5913 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005914 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005915 if (status < 0)
5916 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005917 return status;
5918}
5919
5920
5921static int PowerDownDevice(struct drxk_state *state)
5922{
5923 /* Power down to requested mode */
5924 /* Backup some register settings */
5925 /* Set pins with possible pull-ups connected to them in input mode */
5926 /* Analog power down */
5927 /* ADC power down */
5928 /* Power down device */
5929 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005930
5931 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005932 if (state->m_bPDownOpenBridge) {
5933 /* Open I2C bridge before power down of DRXK */
5934 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005935 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005936 goto error;
5937 }
5938 /* driver 0.9.0 */
5939 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005940 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005941 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005942
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005943 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5944 if (status < 0)
5945 goto error;
5946 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5947 if (status < 0)
5948 goto error;
5949 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5950 status = HI_CfgCommand(state);
5951error:
5952 if (status < 0)
5953 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5954
5955 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005956}
5957
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005958static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005959{
5960 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005961 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005962
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005963 dprintk(1, "\n");
5964
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005965 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5966 if (err < 0) {
5967 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005968 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005969 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005970 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005971 return err;
5972 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005973 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005974 release_firmware(fw);
5975 return err;
5976}
5977
5978static int init_drxk(struct drxk_state *state)
5979{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005980 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005981 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005982 u16 driverVersion;
5983
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005984 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005985 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005986 status = PowerUpDevice(state);
5987 if (status < 0)
5988 goto error;
5989 status = DRXX_Open(state);
5990 if (status < 0)
5991 goto error;
5992 /* Soft reset of OFDM-, sys- and osc-clockdomain */
5993 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);
5994 if (status < 0)
5995 goto error;
5996 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5997 if (status < 0)
5998 goto error;
5999 /* TODO is this needed, if yes how much delay in worst case scenario */
6000 msleep(1);
6001 state->m_DRXK_A3_PATCH_CODE = true;
6002 status = GetDeviceCapabilities(state);
6003 if (status < 0)
6004 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006005
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006006 /* Bridge delay, uses oscilator clock */
6007 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6008 /* SDA brdige delay */
6009 state->m_HICfgBridgeDelay =
6010 (u16) ((state->m_oscClockFreq / 1000) *
6011 HI_I2C_BRIDGE_DELAY) / 1000;
6012 /* Clipping */
6013 if (state->m_HICfgBridgeDelay >
6014 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006015 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006016 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6017 }
6018 /* SCL bridge delay, same as SDA for now */
6019 state->m_HICfgBridgeDelay +=
6020 state->m_HICfgBridgeDelay <<
6021 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006022
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006023 status = InitHI(state);
6024 if (status < 0)
6025 goto error;
6026 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006027#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006028 if (!(state->m_DRXK_A1_ROM_CODE)
6029 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006030#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006031 {
6032 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6033 if (status < 0)
6034 goto error;
6035 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006036
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006037 /* disable MPEG port */
6038 status = MPEGTSDisable(state);
6039 if (status < 0)
6040 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006041
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006042 /* Stop AUD and SCU */
6043 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6044 if (status < 0)
6045 goto error;
6046 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6047 if (status < 0)
6048 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006049
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006050 /* enable token-ring bus through OFDM block for possible ucode upload */
6051 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6052 if (status < 0)
6053 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006054
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006055 /* include boot loader section */
6056 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6057 if (status < 0)
6058 goto error;
6059 status = BLChainCmd(state, 0, 6, 100);
6060 if (status < 0)
6061 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006062
Mauro Carvalho Chehabda989e02011-07-24 09:25:39 -03006063 if (state->microcode_name)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006064 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006065
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006066 /* disable token-ring bus through OFDM block for possible ucode upload */
6067 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6068 if (status < 0)
6069 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006070
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006071 /* Run SCU for a little while to initialize microcode version numbers */
6072 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6073 if (status < 0)
6074 goto error;
6075 status = DRXX_Open(state);
6076 if (status < 0)
6077 goto error;
6078 /* added for test */
6079 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006080
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006081 powerMode = DRXK_POWER_DOWN_OFDM;
6082 status = CtrlPowerMode(state, &powerMode);
6083 if (status < 0)
6084 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006085
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006086 /* Stamp driver version number in SCU data RAM in BCD code
6087 Done to enable field application engineers to retreive drxdriver version
6088 via I2C from SCU RAM.
6089 Not using SCU command interface for SCU register access since no
6090 microcode may be present.
6091 */
6092 driverVersion =
6093 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6094 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6095 ((DRXK_VERSION_MAJOR % 10) << 4) +
6096 (DRXK_VERSION_MINOR % 10);
6097 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6098 if (status < 0)
6099 goto error;
6100 driverVersion =
6101 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6102 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6103 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6104 (DRXK_VERSION_PATCH % 10);
6105 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6106 if (status < 0)
6107 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006108
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006109 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6110 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6111 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006112
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006113 /* Dirty fix of default values for ROM/PATCH microcode
6114 Dirty because this fix makes it impossible to setup suitable values
6115 before calling DRX_Open. This solution requires changes to RF AGC speed
6116 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006117
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006118 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006119
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006120 /* Reset driver debug flags to 0 */
6121 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6122 if (status < 0)
6123 goto error;
6124 /* driver 0.9.0 */
6125 /* Setup FEC OC:
6126 NOTE: No more full FEC resets allowed afterwards!! */
6127 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6128 if (status < 0)
6129 goto error;
6130 /* MPEGTS functions are still the same */
6131 status = MPEGTSDtoInit(state);
6132 if (status < 0)
6133 goto error;
6134 status = MPEGTSStop(state);
6135 if (status < 0)
6136 goto error;
6137 status = MPEGTSConfigurePolarity(state);
6138 if (status < 0)
6139 goto error;
6140 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6141 if (status < 0)
6142 goto error;
6143 /* added: configure GPIO */
6144 status = WriteGPIO(state);
6145 if (status < 0)
6146 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006147
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006148 state->m_DrxkState = DRXK_STOPPED;
6149
6150 if (state->m_bPowerDown) {
6151 status = PowerDownDevice(state);
6152 if (status < 0)
6153 goto error;
6154 state->m_DrxkState = DRXK_POWERED_DOWN;
6155 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006156 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006157 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006158error:
6159 if (status < 0)
6160 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006161
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006162 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006163}
6164
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006165static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006166{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006167 struct drxk_state *state = fe->demodulator_priv;
6168
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006169 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006170 kfree(state);
6171}
6172
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006173static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006174{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006175 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006176
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006177 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006178 ShutDown(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006179 return 0;
6180}
6181
Oliver Endrissebc7de22011-07-03 13:49:44 -03006182static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006183{
6184 struct drxk_state *state = fe->demodulator_priv;
6185
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006186 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006187 return ConfigureI2CBridge(state, enable ? true : false);
6188}
6189
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006190static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006191{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006192 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006193 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006194 struct drxk_state *state = fe->demodulator_priv;
6195 u32 IF;
6196
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006197 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006198
6199 if (!fe->ops.tuner_ops.get_if_frequency) {
6200 printk(KERN_ERR
6201 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6202 return -EINVAL;
6203 }
6204
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006205 if (fe->ops.i2c_gate_ctrl)
6206 fe->ops.i2c_gate_ctrl(fe, 1);
6207 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006208 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006209 if (fe->ops.i2c_gate_ctrl)
6210 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006211
6212 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006213 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006214
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006215 if (old_delsys != delsys) {
6216 ShutDown(state);
6217 switch (delsys) {
6218 case SYS_DVBC_ANNEX_A:
6219 case SYS_DVBC_ANNEX_C:
6220 if (!state->m_hasDVBC)
6221 return -EINVAL;
6222 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6223 if (state->m_itut_annex_c)
6224 SetOperationMode(state, OM_QAM_ITU_C);
6225 else
6226 SetOperationMode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006227 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006228 case SYS_DVBT:
6229 if (!state->m_hasDVBT)
6230 return -EINVAL;
6231 SetOperationMode(state, OM_DVBT);
6232 break;
6233 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006234 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006235 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006236 }
6237
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006238 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006239 Start(state, 0, IF);
6240
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006241 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006242
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006243 return 0;
6244}
6245
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006246static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6247{
6248 struct drxk_state *state = fe->demodulator_priv;
6249 u32 stat;
6250
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006251 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006252 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006253 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006254 if (stat == MPEG_LOCK)
6255 *status |= 0x1f;
6256 if (stat == FEC_LOCK)
6257 *status |= 0x0f;
6258 if (stat == DEMOD_LOCK)
6259 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006260 return 0;
6261}
6262
6263static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6264{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006265 dprintk(1, "\n");
6266
Oliver Endrissebc7de22011-07-03 13:49:44 -03006267 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006268 return 0;
6269}
6270
Oliver Endrissebc7de22011-07-03 13:49:44 -03006271static int drxk_read_signal_strength(struct dvb_frontend *fe,
6272 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006273{
6274 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006275 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006276
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006277 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006278 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006279 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006280 return 0;
6281}
6282
6283static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6284{
6285 struct drxk_state *state = fe->demodulator_priv;
6286 s32 snr2;
6287
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006288 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006289 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006290 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006291 return 0;
6292}
6293
6294static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6295{
6296 struct drxk_state *state = fe->demodulator_priv;
6297 u16 err;
6298
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006299 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006300 DVBTQAMGetAccPktErr(state, &err);
6301 *ucblocks = (u32) err;
6302 return 0;
6303}
6304
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006305static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006306 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006307{
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006308 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006309
6310 dprintk(1, "\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006311 switch (p->delivery_system) {
6312 case SYS_DVBC_ANNEX_A:
6313 case SYS_DVBC_ANNEX_C:
6314 sets->min_delay_ms = 3000;
6315 sets->max_drift = 0;
6316 sets->step_size = 0;
6317 return 0;
6318 default:
6319 /*
6320 * For DVB-T, let it use the default DVB core way, that is:
6321 * fepriv->step_size = fe->ops.info.frequency_stepsize * 2
6322 */
6323 return -EINVAL;
6324 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006325}
6326
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006327static struct dvb_frontend_ops drxk_ops = {
6328 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006329 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006330 .name = "DRXK",
6331 .frequency_min = 47000000,
6332 .frequency_max = 865000000,
6333 /* For DVB-C */
6334 .symbol_rate_min = 870000,
6335 .symbol_rate_max = 11700000,
6336 /* For DVB-T */
6337 .frequency_stepsize = 166667,
6338
6339 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6340 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6341 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6342 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6343 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6344 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6345 },
6346
6347 .release = drxk_release,
6348 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006349 .i2c_gate_ctrl = drxk_gate_ctrl,
6350
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006351 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006352 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006353
6354 .read_status = drxk_read_status,
6355 .read_ber = drxk_read_ber,
6356 .read_signal_strength = drxk_read_signal_strength,
6357 .read_snr = drxk_read_snr,
6358 .read_ucblocks = drxk_read_ucblocks,
6359};
6360
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006361struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006362 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006363{
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006364 int n;
6365
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006366 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006367 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006368
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006369 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006370 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006371 if (!state)
6372 return NULL;
6373
Oliver Endrissebc7de22011-07-03 13:49:44 -03006374 state->i2c = i2c;
6375 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006376 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006377 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006378 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006379 state->antenna_gpio = config->antenna_gpio;
6380 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006381 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006382
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006383 if (config->dynamic_clk) {
6384 state->m_DVBTStaticCLK = 0;
6385 state->m_DVBCStaticCLK = 0;
6386 } else {
6387 state->m_DVBTStaticCLK = 1;
6388 state->m_DVBCStaticCLK = 1;
6389 }
6390
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006391
6392 if (config->mpeg_out_clk_strength)
6393 state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
6394 else
6395 state->m_TSClockkStrength = 0x06;
6396
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006397 if (config->parallel_ts)
6398 state->m_enableParallel = true;
6399 else
6400 state->m_enableParallel = false;
6401
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006402 /* NOTE: as more UIO bits will be used, add them to the mask */
6403 state->UIO_mask = config->antenna_gpio;
6404
6405 /* Default gpio to DVB-C */
6406 if (!state->antenna_dvbt && state->antenna_gpio)
6407 state->m_GPIO |= state->antenna_gpio;
6408 else
6409 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006410
6411 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006412
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006413 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6414 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006415
6416 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006417 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006418 goto error;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006419
6420 /* Initialize the supported delivery systems */
6421 n = 0;
6422 if (state->m_hasDVBC) {
6423 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6424 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6425 strlcat(state->frontend.ops.info.name, " DVB-C",
6426 sizeof(state->frontend.ops.info.name));
6427 }
6428 if (state->m_hasDVBT) {
6429 state->frontend.ops.delsys[n++] = SYS_DVBT;
6430 strlcat(state->frontend.ops.info.name, " DVB-T",
6431 sizeof(state->frontend.ops.info.name));
6432 }
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006433
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006434 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006435 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006436
6437error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006438 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006439 kfree(state);
6440 return NULL;
6441}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006442EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006443
6444MODULE_DESCRIPTION("DRX-K driver");
6445MODULE_AUTHOR("Ralph Metzler");
6446MODULE_LICENSE("GPL");