blob: a95fb44cbba383b7e414e917c5746a829bacd80c [file] [log] [blame]
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001/*
2 * drxk_hard: DRX-K DVB-C/T demodulator driver
3 *
4 * Copyright (C) 2010-2011 Digital Devices GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/firmware.h>
30#include <linux/i2c.h>
31#include <linux/version.h>
32#include <asm/div64.h>
33
34#include "dvb_frontend.h"
35#include "drxk.h"
36#include "drxk_hard.h"
37
38static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
39static int PowerDownQAM(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030040static int SetDVBTStandard(struct drxk_state *state,
41 enum OperationMode oMode);
42static int SetQAMStandard(struct drxk_state *state,
43 enum OperationMode oMode);
44static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
Ralph Metzler43dd07f2011-07-03 13:42:18 -030045 s32 tunerFreqOffset);
Oliver Endrissebc7de22011-07-03 13:49:44 -030046static int SetDVBTStandard(struct drxk_state *state,
47 enum OperationMode oMode);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030048static int DVBTStart(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030049static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
50 s32 tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030051static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
52static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
53static int SwitchAntennaToQAM(struct drxk_state *state);
54static int SwitchAntennaToDVBT(struct drxk_state *state);
55
56static bool IsDVBT(struct drxk_state *state)
57{
58 return state->m_OperationMode == OM_DVBT;
59}
60
61static bool IsQAM(struct drxk_state *state)
62{
63 return state->m_OperationMode == OM_QAM_ITU_A ||
Oliver Endrissebc7de22011-07-03 13:49:44 -030064 state->m_OperationMode == OM_QAM_ITU_B ||
65 state->m_OperationMode == OM_QAM_ITU_C;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030066}
67
68bool IsA1WithPatchCode(struct drxk_state *state)
69{
70 return state->m_DRXK_A1_PATCH_CODE;
71}
72
73bool IsA1WithRomCode(struct drxk_state *state)
74{
75 return state->m_DRXK_A1_ROM_CODE;
76}
77
78#define NOA1ROM 0
79
Ralph Metzler43dd07f2011-07-03 13:42:18 -030080#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
81#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
82
83#define DEFAULT_MER_83 165
84#define DEFAULT_MER_93 250
85
86#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
87#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
88#endif
89
90#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
91#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
92#endif
93
94#ifndef DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH
95#define DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH (0x06)
96#endif
97
98#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
99#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
100
101#ifndef DRXK_KI_RAGC_ATV
102#define DRXK_KI_RAGC_ATV 4
103#endif
104#ifndef DRXK_KI_IAGC_ATV
105#define DRXK_KI_IAGC_ATV 6
106#endif
107#ifndef DRXK_KI_DAGC_ATV
108#define DRXK_KI_DAGC_ATV 7
109#endif
110
111#ifndef DRXK_KI_RAGC_QAM
112#define DRXK_KI_RAGC_QAM 3
113#endif
114#ifndef DRXK_KI_IAGC_QAM
115#define DRXK_KI_IAGC_QAM 4
116#endif
117#ifndef DRXK_KI_DAGC_QAM
118#define DRXK_KI_DAGC_QAM 7
119#endif
120#ifndef DRXK_KI_RAGC_DVBT
121#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
122#endif
123#ifndef DRXK_KI_IAGC_DVBT
124#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
125#endif
126#ifndef DRXK_KI_DAGC_DVBT
127#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
128#endif
129
130#ifndef DRXK_AGC_DAC_OFFSET
131#define DRXK_AGC_DAC_OFFSET (0x800)
132#endif
133
134#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
135#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
136#endif
137
138#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
139#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
140#endif
141
142#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
143#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
144#endif
145
146#ifndef DRXK_QAM_SYMBOLRATE_MAX
147#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
148#endif
149
150#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
151#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
152#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
153#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
154#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
155#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
156#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
157#define DRXK_BL_ROM_OFFSET_UCODE 0
158
159#define DRXK_BLC_TIMEOUT 100
160
161#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
162#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
163
164#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
165
166#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
167#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
168#endif
169
170#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
171#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
172#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
173#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
174#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
175
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300176static unsigned int debug;
177module_param(debug, int, 0644);
178MODULE_PARM_DESC(debug, "enable debug messages");
179
180#define dprintk(level, fmt, arg...) do { \
181if (debug >= level) \
182 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
183} while (0)
184
185
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300186static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300187{
188 u64 tmp64;
189
Oliver Endrissebc7de22011-07-03 13:49:44 -0300190 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300191 do_div(tmp64, c);
192
193 return (u32) tmp64;
194}
195
196inline u32 Frac28a(u32 a, u32 c)
197{
198 int i = 0;
199 u32 Q1 = 0;
200 u32 R0 = 0;
201
Oliver Endrissebc7de22011-07-03 13:49:44 -0300202 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
203 Q1 = a / c; /* integer part, only the 4 least significant bits
204 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300205
206 /* division using radix 16, 7 nibbles in the result */
207 for (i = 0; i < 7; i++) {
208 Q1 = (Q1 << 4) | (R0 / c);
209 R0 = (R0 % c) << 4;
210 }
211 /* rounding */
212 if ((R0 >> 3) >= c)
213 Q1++;
214
215 return Q1;
216}
217
218static u32 Log10Times100(u32 x)
219{
220 static const u8 scale = 15;
221 static const u8 indexWidth = 5;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300222 u8 i = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300223 u32 y = 0;
224 u32 d = 0;
225 u32 k = 0;
226 u32 r = 0;
227 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300228 log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
229 0 <= n < ((1<<INDEXWIDTH)+1)
230 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300231
232 static const u32 log2lut[] = {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300233 0, /* 0.000000 */
234 290941, /* 290941.300628 */
235 573196, /* 573196.476418 */
236 847269, /* 847269.179851 */
237 1113620, /* 1113620.489452 */
238 1372674, /* 1372673.576986 */
239 1624818, /* 1624817.752104 */
240 1870412, /* 1870411.981536 */
241 2109788, /* 2109787.962654 */
242 2343253, /* 2343252.817465 */
243 2571091, /* 2571091.461923 */
244 2793569, /* 2793568.696416 */
245 3010931, /* 3010931.055901 */
246 3223408, /* 3223408.452106 */
247 3431216, /* 3431215.635215 */
248 3634553, /* 3634553.498355 */
249 3833610, /* 3833610.244726 */
250 4028562, /* 4028562.434393 */
251 4219576, /* 4219575.925308 */
252 4406807, /* 4406806.721144 */
253 4590402, /* 4590401.736809 */
254 4770499, /* 4770499.491025 */
255 4947231, /* 4947230.734179 */
256 5120719, /* 5120719.018555 */
257 5291081, /* 5291081.217197 */
258 5458428, /* 5458427.996830 */
259 5622864, /* 5622864.249668 */
260 5784489, /* 5784489.488298 */
261 5943398, /* 5943398.207380 */
262 6099680, /* 6099680.215452 */
263 6253421, /* 6253420.939751 */
264 6404702, /* 6404701.706649 */
265 6553600, /* 6553600.000000 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300266 };
267
268
269 if (x == 0)
Oliver Endrissebc7de22011-07-03 13:49:44 -0300270 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300271
272 /* Scale x (normalize) */
273 /* computing y in log(x/y) = log(x) - log(y) */
274 if ((x & ((0xffffffff) << (scale + 1))) == 0) {
275 for (k = scale; k > 0; k--) {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300276 if (x & (((u32) 1) << scale))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300277 break;
278 x <<= 1;
279 }
280 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300281 for (k = scale; k < 31; k++) {
282 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300283 break;
284 x >>= 1;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300285 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300286 }
287 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300288 Now x has binary point between bit[scale] and bit[scale-1]
289 and 1.0 <= x < 2.0 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300290
291 /* correction for divison: log(x) = log(x/y)+log(y) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300292 y = k * ((((u32) 1) << scale) * 200);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300293
294 /* remove integer part */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300295 x &= ((((u32) 1) << scale) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300296 /* get index */
297 i = (u8) (x >> (scale - indexWidth));
298 /* compute delta (x - a) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300299 d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300300 /* compute log, multiplication (d* (..)) must be within range ! */
301 y += log2lut[i] +
Oliver Endrissebc7de22011-07-03 13:49:44 -0300302 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300303 /* Conver to log10() */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300304 y /= 108853; /* (log2(10) << scale) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300305 r = (y >> 1);
306 /* rounding */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300307 if (y & ((u32) 1))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300308 r++;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300309 return r;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300310}
311
312/****************************************************************************/
313/* I2C **********************************************************************/
314/****************************************************************************/
315
316static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val)
317{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300318 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
319 .buf = val, .len = 1}
320 };
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300321
322 return i2c_transfer(adapter, msgs, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300323}
324
325static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
326{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300327 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300328 struct i2c_msg msg = {
329 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300330
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300331 dprintk(3, ":");
332 if (debug > 2) {
333 int i;
334 for (i = 0; i < len; i++)
335 printk(KERN_CONT " %02x", data[i]);
336 printk(KERN_CONT "\n");
337 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300338 status = i2c_transfer(adap, &msg, 1);
339 if (status >= 0 && status != 1)
340 status = -EIO;
341
342 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300343 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300344
345 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300346}
347
348static int i2c_read(struct i2c_adapter *adap,
349 u8 adr, u8 *msg, int len, u8 *answ, int alen)
350{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300351 int status;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300352 struct i2c_msg msgs[2] = {
353 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300354 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300355 {.addr = adr, .flags = I2C_M_RD,
356 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300357 };
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300358
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300359 status = i2c_transfer(adap, msgs, 2);
360 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300361 if (debug > 2)
362 printk(KERN_CONT ": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300363 if (status >= 0)
364 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300365
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300366 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300367 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300368 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300369 if (debug > 2) {
370 int i;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300371 dprintk(2, ": read from");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300372 for (i = 0; i < len; i++)
373 printk(KERN_CONT " %02x", msg[i]);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300374 printk(KERN_CONT ", value = ");
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300375 for (i = 0; i < alen; i++)
376 printk(KERN_CONT " %02x", answ[i]);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300377 printk(KERN_CONT "\n");
378 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300379 return 0;
380}
381
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300382static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300383{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300384 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300385 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300386
387 if (state->single_master)
388 flags |= 0xC0;
389
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300390 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
391 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
392 mm1[1] = ((reg >> 16) & 0xFF);
393 mm1[2] = ((reg >> 24) & 0xFF) | flags;
394 mm1[3] = ((reg >> 7) & 0xFF);
395 len = 4;
396 } else {
397 mm1[0] = ((reg << 1) & 0xFF);
398 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
399 len = 2;
400 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300401 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300402 status = i2c_read(state->i2c, adr, mm1, len, mm2, 2);
403 if (status < 0)
404 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300405 if (data)
406 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300407
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300408 return 0;
409}
410
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300411static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300412{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300413 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300414}
415
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300416static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300417{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300418 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300419 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300420
421 if (state->single_master)
422 flags |= 0xC0;
423
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300424 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
425 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
426 mm1[1] = ((reg >> 16) & 0xFF);
427 mm1[2] = ((reg >> 24) & 0xFF) | flags;
428 mm1[3] = ((reg >> 7) & 0xFF);
429 len = 4;
430 } else {
431 mm1[0] = ((reg << 1) & 0xFF);
432 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
433 len = 2;
434 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300435 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300436 status = i2c_read(state->i2c, adr, mm1, len, mm2, 4);
437 if (status < 0)
438 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300439 if (data)
440 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300441 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300442
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300443 return 0;
444}
445
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300446static int read32(struct drxk_state *state, u32 reg, u32 *data)
447{
448 return read32_flags(state, reg, data, 0);
449}
450
451static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300452{
453 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300454
455 if (state->single_master)
456 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300457 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
458 mm[0] = (((reg << 1) & 0xFF) | 0x01);
459 mm[1] = ((reg >> 16) & 0xFF);
460 mm[2] = ((reg >> 24) & 0xFF) | flags;
461 mm[3] = ((reg >> 7) & 0xFF);
462 len = 4;
463 } else {
464 mm[0] = ((reg << 1) & 0xFF);
465 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
466 len = 2;
467 }
468 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300469 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300470
471 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300472 return i2c_write(state->i2c, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300473}
474
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300475static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300476{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300477 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300478}
479
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300480static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300481{
482 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300483
484 if (state->single_master)
485 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300486 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
487 mm[0] = (((reg << 1) & 0xFF) | 0x01);
488 mm[1] = ((reg >> 16) & 0xFF);
489 mm[2] = ((reg >> 24) & 0xFF) | flags;
490 mm[3] = ((reg >> 7) & 0xFF);
491 len = 4;
492 } else {
493 mm[0] = ((reg << 1) & 0xFF);
494 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
495 len = 2;
496 }
497 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300498 mm[len + 1] = (data >> 8) & 0xff;
499 mm[len + 2] = (data >> 16) & 0xff;
500 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300501 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300502
503 return i2c_write(state->i2c, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300504}
505
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300506static int write32(struct drxk_state *state, u32 reg, u32 data)
507{
508 return write32_flags(state, reg, data, 0);
509}
510
511static int write_block(struct drxk_state *state, u32 Address,
512 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300513{
514 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300515 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300516
517 if (state->single_master)
518 Flags |= 0xC0;
519
Oliver Endrissebc7de22011-07-03 13:49:44 -0300520 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300521 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300522 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300523 u8 *AdrBuf = &state->Chunk[0];
524 u32 AdrLength = 0;
525
Oliver Endrissebc7de22011-07-03 13:49:44 -0300526 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
527 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
528 AdrBuf[1] = ((Address >> 16) & 0xFF);
529 AdrBuf[2] = ((Address >> 24) & 0xFF);
530 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300531 AdrBuf[2] |= Flags;
532 AdrLength = 4;
533 if (Chunk == state->m_ChunkSize)
534 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300535 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300536 AdrBuf[0] = ((Address << 1) & 0xFF);
537 AdrBuf[1] = (((Address >> 16) & 0x0F) |
538 ((Address >> 18) & 0xF0));
539 AdrLength = 2;
540 }
541 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300542 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
543 if (debug > 1) {
544 int i;
545 if (pBlock)
546 for (i = 0; i < Chunk; i++)
547 printk(KERN_CONT " %02x", pBlock[i]);
548 printk(KERN_CONT "\n");
549 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300550 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300551 &state->Chunk[0], Chunk + AdrLength);
552 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300553 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
554 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300555 break;
556 }
557 pBlock += Chunk;
558 Address += (Chunk >> 1);
559 BlkSize -= Chunk;
560 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300561 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300562}
563
564#ifndef DRXK_MAX_RETRIES_POWERUP
565#define DRXK_MAX_RETRIES_POWERUP 20
566#endif
567
568int PowerUpDevice(struct drxk_state *state)
569{
570 int status;
571 u8 data = 0;
572 u16 retryCount = 0;
573
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300574 dprintk(1, "\n");
575
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300576 status = i2c_read1(state->i2c, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300577 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300578 do {
579 data = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300580 status = i2c_write(state->i2c, state->demod_address,
581 &data, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300582 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300583 retryCount++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300584 if (status < 0)
585 continue;
586 status = i2c_read1(state->i2c, state->demod_address,
587 &data);
588 } while (status < 0 &&
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300589 (retryCount < DRXK_MAX_RETRIES_POWERUP));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300590 if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
591 goto error;
592 }
593
594 /* Make sure all clk domains are active */
595 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
596 if (status < 0)
597 goto error;
598 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
599 if (status < 0)
600 goto error;
601 /* Enable pll lock tests */
602 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
603 if (status < 0)
604 goto error;
605
606 state->m_currentPowerMode = DRX_POWER_UP;
607
608error:
609 if (status < 0)
610 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
611
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300612 return status;
613}
614
615
616static int init_state(struct drxk_state *state)
617{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -0300618 /*
619 * FIXME: most (all?) of the values bellow should be moved into
620 * struct drxk_config, as they are probably board-specific
621 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300622 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
623 u32 ulVSBIfAgcOutputLevel = 0;
624 u32 ulVSBIfAgcMinLevel = 0;
625 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
626 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300627
Oliver Endrissebc7de22011-07-03 13:49:44 -0300628 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
629 u32 ulVSBRfAgcOutputLevel = 0;
630 u32 ulVSBRfAgcMinLevel = 0;
631 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
632 u32 ulVSBRfAgcSpeed = 3;
633 u32 ulVSBRfAgcTop = 9500;
634 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300635
Oliver Endrissebc7de22011-07-03 13:49:44 -0300636 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
637 u32 ulATVIfAgcOutputLevel = 0;
638 u32 ulATVIfAgcMinLevel = 0;
639 u32 ulATVIfAgcMaxLevel = 0;
640 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300641
Oliver Endrissebc7de22011-07-03 13:49:44 -0300642 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
643 u32 ulATVRfAgcOutputLevel = 0;
644 u32 ulATVRfAgcMinLevel = 0;
645 u32 ulATVRfAgcMaxLevel = 0;
646 u32 ulATVRfAgcTop = 9500;
647 u32 ulATVRfAgcCutOffCurrent = 4000;
648 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300649
650 u32 ulQual83 = DEFAULT_MER_83;
651 u32 ulQual93 = DEFAULT_MER_93;
652
653 u32 ulDVBTStaticTSClock = 1;
654 u32 ulDVBCStaticTSClock = 1;
655
656 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
657 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
658
659 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
660 /* io_pad_cfg_mode output mode is drive always */
661 /* io_pad_cfg_drive is set to power 2 (23 mA) */
662 u32 ulGPIOCfg = 0x0113;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300663 u32 ulInvertTSClock = 0;
664 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
665 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
666 u32 ulDVBTBitrate = 50000000;
667 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
668
669 u32 ulInsertRSByte = 0;
670
671 u32 ulRfMirror = 1;
672 u32 ulPowerDown = 0;
673
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300674 dprintk(1, "\n");
675
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300676 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300677 state->m_hasDVBT = false;
678 state->m_hasDVBC = false;
679 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300680 state->m_hasOOB = false;
681 state->m_hasAudio = false;
682
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -0300683 if (!state->m_ChunkSize)
Mauro Carvalho Chehabde724052011-11-20 11:23:24 -0200684 state->m_ChunkSize = 124;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300685
686 state->m_oscClockFreq = 0;
687 state->m_smartAntInverted = false;
688 state->m_bPDownOpenBridge = false;
689
690 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300691 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300692 /* Timing div, 250ns/Psys */
693 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
694 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
695 HI_I2C_DELAY) / 1000;
696 /* Clipping */
697 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
698 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
699 state->m_HICfgWakeUpKey = (state->demod_address << 1);
700 /* port/bridge/power down ctrl */
701 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
702
703 state->m_bPowerDown = (ulPowerDown != 0);
704
705 state->m_DRXK_A1_PATCH_CODE = false;
706 state->m_DRXK_A1_ROM_CODE = false;
707 state->m_DRXK_A2_ROM_CODE = false;
708 state->m_DRXK_A3_ROM_CODE = false;
709 state->m_DRXK_A2_PATCH_CODE = false;
710 state->m_DRXK_A3_PATCH_CODE = false;
711
712 /* Init AGC and PGA parameters */
713 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300714 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
715 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
716 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
717 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
718 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300719 state->m_vsbPgaCfg = 140;
720
721 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300722 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
723 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
724 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
725 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
726 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
727 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
728 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
729 state->m_vsbPreSawCfg.reference = 0x07;
730 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300731
732 state->m_Quality83percent = DEFAULT_MER_83;
733 state->m_Quality93percent = DEFAULT_MER_93;
734 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
735 state->m_Quality83percent = ulQual83;
736 state->m_Quality93percent = ulQual93;
737 }
738
739 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300740 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
741 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
742 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
743 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
744 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300745
746 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300747 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
748 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
749 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
750 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
751 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
752 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
753 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
754 state->m_atvPreSawCfg.reference = 0x04;
755 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300756
757
758 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300759 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
760 state->m_dvbtRfAgcCfg.outputLevel = 0;
761 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
762 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
763 state->m_dvbtRfAgcCfg.top = 0x2100;
764 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
765 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300766
767
768 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300769 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
770 state->m_dvbtIfAgcCfg.outputLevel = 0;
771 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
772 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
773 state->m_dvbtIfAgcCfg.top = 13424;
774 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
775 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300776 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300777 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
778 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300779
Oliver Endrissebc7de22011-07-03 13:49:44 -0300780 state->m_dvbtPreSawCfg.reference = 4;
781 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300782
783 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300784 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
785 state->m_qamRfAgcCfg.outputLevel = 0;
786 state->m_qamRfAgcCfg.minOutputLevel = 6023;
787 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
788 state->m_qamRfAgcCfg.top = 0x2380;
789 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
790 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300791
792 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300793 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
794 state->m_qamIfAgcCfg.outputLevel = 0;
795 state->m_qamIfAgcCfg.minOutputLevel = 0;
796 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
797 state->m_qamIfAgcCfg.top = 0x0511;
798 state->m_qamIfAgcCfg.cutOffCurrent = 0;
799 state->m_qamIfAgcCfg.speed = 3;
800 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300801 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
802
Oliver Endrissebc7de22011-07-03 13:49:44 -0300803 state->m_qamPgaCfg = 140;
804 state->m_qamPreSawCfg.reference = 4;
805 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300806
807 state->m_OperationMode = OM_NONE;
808 state->m_DrxkState = DRXK_UNINITIALIZED;
809
810 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300811 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
812 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300813 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
814 state->m_invertERR = false; /* If TRUE; invert ERR signal */
815 state->m_invertSTR = false; /* If TRUE; invert STR signals */
816 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
817 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300818 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300819 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300820 /* If TRUE; static MPEG clockrate will be used;
821 otherwise clockrate will adapt to the bitrate of the TS */
822
823 state->m_DVBTBitrate = ulDVBTBitrate;
824 state->m_DVBCBitrate = ulDVBCBitrate;
825
826 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
827 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
828
829 /* Maximum bitrate in b/s in case static clockrate is selected */
830 state->m_mpegTsStaticBitrate = 19392658;
831 state->m_disableTEIhandling = false;
832
833 if (ulInsertRSByte)
834 state->m_insertRSByte = true;
835
836 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
837 if (ulMpegLockTimeOut < 10000)
838 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
839 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
840 if (ulDemodLockTimeOut < 10000)
841 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
842
Oliver Endrissebc7de22011-07-03 13:49:44 -0300843 /* QAM defaults */
844 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300845 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300846 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
847 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300848
849 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
850 state->m_agcFastClipCtrlDelay = 0;
851
852 state->m_GPIOCfg = (ulGPIOCfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300853
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300854 state->m_bPowerDown = false;
855 state->m_currentPowerMode = DRX_POWER_DOWN;
856
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300857 state->m_rfmirror = (ulRfMirror == 0);
858 state->m_IfAgcPol = false;
859 return 0;
860}
861
862static int DRXX_Open(struct drxk_state *state)
863{
864 int status = 0;
865 u32 jtag = 0;
866 u16 bid = 0;
867 u16 key = 0;
868
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300869 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300870 /* stop lock indicator process */
871 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
872 if (status < 0)
873 goto error;
874 /* Check device id */
875 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
876 if (status < 0)
877 goto error;
878 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
879 if (status < 0)
880 goto error;
881 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
882 if (status < 0)
883 goto error;
884 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
885 if (status < 0)
886 goto error;
887 status = write16(state, SIO_TOP_COMM_KEY__A, key);
888error:
889 if (status < 0)
890 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300891 return status;
892}
893
894static int GetDeviceCapabilities(struct drxk_state *state)
895{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300896 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300897 u32 sioTopJtagidLo = 0;
898 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300899 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300900
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300901 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300902
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300903 /* driver 0.9.0 */
904 /* stop lock indicator process */
905 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
906 if (status < 0)
907 goto error;
908 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
909 if (status < 0)
910 goto error;
911 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
912 if (status < 0)
913 goto error;
914 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
915 if (status < 0)
916 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300917
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300918 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
919 case 0:
920 /* ignore (bypass ?) */
921 break;
922 case 1:
923 /* 27 MHz */
924 state->m_oscClockFreq = 27000;
925 break;
926 case 2:
927 /* 20.25 MHz */
928 state->m_oscClockFreq = 20250;
929 break;
930 case 3:
931 /* 4 MHz */
932 state->m_oscClockFreq = 20250;
933 break;
934 default:
935 printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
936 return -EINVAL;
937 }
938 /*
939 Determine device capabilities
940 Based on pinning v14
941 */
942 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
943 if (status < 0)
944 goto error;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300945
946printk(KERN_ERR "drxk: status = 0x%08x\n", sioTopJtagidLo);
947
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300948 /* driver 0.9.0 */
949 switch ((sioTopJtagidLo >> 29) & 0xF) {
950 case 0:
951 state->m_deviceSpin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300952 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300953 break;
954 case 2:
955 state->m_deviceSpin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300956 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300957 break;
958 case 3:
959 state->m_deviceSpin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300960 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300961 break;
962 default:
963 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
964 status = -EINVAL;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300965 printk(KERN_ERR "drxk: Spin %d unknown\n",
966 (sioTopJtagidLo >> 29) & 0xF);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300967 goto error2;
968 }
969 switch ((sioTopJtagidLo >> 12) & 0xFF) {
970 case 0x13:
971 /* typeId = DRX3913K_TYPE_ID */
972 state->m_hasLNA = false;
973 state->m_hasOOB = false;
974 state->m_hasATV = false;
975 state->m_hasAudio = false;
976 state->m_hasDVBT = true;
977 state->m_hasDVBC = true;
978 state->m_hasSAWSW = true;
979 state->m_hasGPIO2 = false;
980 state->m_hasGPIO1 = false;
981 state->m_hasIRQN = false;
982 break;
983 case 0x15:
984 /* typeId = DRX3915K_TYPE_ID */
985 state->m_hasLNA = false;
986 state->m_hasOOB = false;
987 state->m_hasATV = true;
988 state->m_hasAudio = false;
989 state->m_hasDVBT = true;
990 state->m_hasDVBC = false;
991 state->m_hasSAWSW = true;
992 state->m_hasGPIO2 = true;
993 state->m_hasGPIO1 = true;
994 state->m_hasIRQN = false;
995 break;
996 case 0x16:
997 /* typeId = DRX3916K_TYPE_ID */
998 state->m_hasLNA = false;
999 state->m_hasOOB = false;
1000 state->m_hasATV = true;
1001 state->m_hasAudio = false;
1002 state->m_hasDVBT = true;
1003 state->m_hasDVBC = false;
1004 state->m_hasSAWSW = true;
1005 state->m_hasGPIO2 = true;
1006 state->m_hasGPIO1 = true;
1007 state->m_hasIRQN = false;
1008 break;
1009 case 0x18:
1010 /* typeId = DRX3918K_TYPE_ID */
1011 state->m_hasLNA = false;
1012 state->m_hasOOB = false;
1013 state->m_hasATV = true;
1014 state->m_hasAudio = true;
1015 state->m_hasDVBT = true;
1016 state->m_hasDVBC = false;
1017 state->m_hasSAWSW = true;
1018 state->m_hasGPIO2 = true;
1019 state->m_hasGPIO1 = true;
1020 state->m_hasIRQN = false;
1021 break;
1022 case 0x21:
1023 /* typeId = DRX3921K_TYPE_ID */
1024 state->m_hasLNA = false;
1025 state->m_hasOOB = false;
1026 state->m_hasATV = true;
1027 state->m_hasAudio = true;
1028 state->m_hasDVBT = true;
1029 state->m_hasDVBC = true;
1030 state->m_hasSAWSW = true;
1031 state->m_hasGPIO2 = true;
1032 state->m_hasGPIO1 = true;
1033 state->m_hasIRQN = false;
1034 break;
1035 case 0x23:
1036 /* typeId = DRX3923K_TYPE_ID */
1037 state->m_hasLNA = false;
1038 state->m_hasOOB = false;
1039 state->m_hasATV = true;
1040 state->m_hasAudio = true;
1041 state->m_hasDVBT = true;
1042 state->m_hasDVBC = true;
1043 state->m_hasSAWSW = true;
1044 state->m_hasGPIO2 = true;
1045 state->m_hasGPIO1 = true;
1046 state->m_hasIRQN = false;
1047 break;
1048 case 0x25:
1049 /* typeId = DRX3925K_TYPE_ID */
1050 state->m_hasLNA = false;
1051 state->m_hasOOB = false;
1052 state->m_hasATV = true;
1053 state->m_hasAudio = true;
1054 state->m_hasDVBT = true;
1055 state->m_hasDVBC = true;
1056 state->m_hasSAWSW = true;
1057 state->m_hasGPIO2 = true;
1058 state->m_hasGPIO1 = true;
1059 state->m_hasIRQN = false;
1060 break;
1061 case 0x26:
1062 /* typeId = DRX3926K_TYPE_ID */
1063 state->m_hasLNA = false;
1064 state->m_hasOOB = false;
1065 state->m_hasATV = true;
1066 state->m_hasAudio = false;
1067 state->m_hasDVBT = true;
1068 state->m_hasDVBC = true;
1069 state->m_hasSAWSW = true;
1070 state->m_hasGPIO2 = true;
1071 state->m_hasGPIO1 = true;
1072 state->m_hasIRQN = false;
1073 break;
1074 default:
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -03001075 printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001076 ((sioTopJtagidLo >> 12) & 0xFF));
1077 status = -EINVAL;
1078 goto error2;
1079 }
1080
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -03001081 printk(KERN_INFO
1082 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
1083 ((sioTopJtagidLo >> 12) & 0xFF), spin,
1084 state->m_oscClockFreq / 1000,
1085 state->m_oscClockFreq % 1000);
1086
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001087error:
1088 if (status < 0)
1089 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1090
1091error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001092 return status;
1093}
1094
1095static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1096{
1097 int status;
1098 bool powerdown_cmd;
1099
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001100 dprintk(1, "\n");
1101
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001102 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001103 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001104 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001105 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001106 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1107 msleep(1);
1108
1109 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001110 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1111 ((state->m_HICfgCtrl) &
1112 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1113 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001114 if (powerdown_cmd == false) {
1115 /* Wait until command rdy */
1116 u32 retryCount = 0;
1117 u16 waitCmd;
1118
1119 do {
1120 msleep(1);
1121 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001122 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1123 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001124 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1125 && (waitCmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001126 if (status < 0)
1127 goto error;
1128 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001129 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001130error:
1131 if (status < 0)
1132 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1133
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001134 return status;
1135}
1136
1137static int HI_CfgCommand(struct drxk_state *state)
1138{
1139 int status;
1140
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001141 dprintk(1, "\n");
1142
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001143 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001144
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001145 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1146 if (status < 0)
1147 goto error;
1148 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1149 if (status < 0)
1150 goto error;
1151 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1152 if (status < 0)
1153 goto error;
1154 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1155 if (status < 0)
1156 goto error;
1157 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1158 if (status < 0)
1159 goto error;
1160 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1161 if (status < 0)
1162 goto error;
1163 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1164 if (status < 0)
1165 goto error;
1166
1167 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1168error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001169 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001170 if (status < 0)
1171 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001172 return status;
1173}
1174
1175static int InitHI(struct drxk_state *state)
1176{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001177 dprintk(1, "\n");
1178
Oliver Endrissebc7de22011-07-03 13:49:44 -03001179 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001180 state->m_HICfgTimeout = 0x96FF;
1181 /* port/bridge/power down ctrl */
1182 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001183
Oliver Endrissebc7de22011-07-03 13:49:44 -03001184 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001185}
1186
1187static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1188{
1189 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001190 u16 sioPdrMclkCfg = 0;
1191 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001192
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03001193 dprintk(1, ": mpeg %s, %s mode\n",
1194 mpegEnable ? "enable" : "disable",
1195 state->m_enableParallel ? "parallel" : "serial");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001196
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001197 /* stop lock indicator process */
1198 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1199 if (status < 0)
1200 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001201
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001202 /* MPEG TS pad configuration */
1203 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1204 if (status < 0)
1205 goto error;
1206
1207 if (mpegEnable == false) {
1208 /* Set MPEG TS pads to inputmode */
1209 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1210 if (status < 0)
1211 goto error;
1212 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1213 if (status < 0)
1214 goto error;
1215 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1216 if (status < 0)
1217 goto error;
1218 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1219 if (status < 0)
1220 goto error;
1221 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1222 if (status < 0)
1223 goto error;
1224 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1225 if (status < 0)
1226 goto error;
1227 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1228 if (status < 0)
1229 goto error;
1230 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1231 if (status < 0)
1232 goto error;
1233 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1234 if (status < 0)
1235 goto error;
1236 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1237 if (status < 0)
1238 goto error;
1239 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1240 if (status < 0)
1241 goto error;
1242 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1243 if (status < 0)
1244 goto error;
1245 } else {
1246 /* Enable MPEG output */
1247 sioPdrMdxCfg =
1248 ((state->m_TSDataStrength <<
1249 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1250 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1251 SIO_PDR_MCLK_CFG_DRIVE__B) |
1252 0x0003);
1253
1254 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1255 if (status < 0)
1256 goto error;
1257 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
1258 if (status < 0)
1259 goto error;
1260 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
1261 if (status < 0)
1262 goto error;
1263 if (state->m_enableParallel == true) {
1264 /* paralel -> enable MD1 to MD7 */
1265 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001266 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001267 goto error;
1268 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001269 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001270 goto error;
1271 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001272 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001273 goto error;
1274 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001275 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001276 goto error;
1277 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001278 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001279 goto error;
1280 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1281 if (status < 0)
1282 goto error;
1283 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1284 if (status < 0)
1285 goto error;
1286 } else {
1287 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1288 SIO_PDR_MD0_CFG_DRIVE__B)
1289 | 0x0003);
1290 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001291 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001292 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001293 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001294 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001295 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001296 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001297 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001298 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001299 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001300 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001301 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001302 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001303 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001304 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001305 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001306 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001307 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001308 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001309 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001310 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001311 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001312 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001313 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001314 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001315 goto error;
1316 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001317 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001318 goto error;
1319 }
1320 /* Enable MB output over MPEG pads and ctl input */
1321 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1322 if (status < 0)
1323 goto error;
1324 /* Write nomagic word to enable pdr reg write */
1325 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1326error:
1327 if (status < 0)
1328 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001329 return status;
1330}
1331
1332static int MPEGTSDisable(struct drxk_state *state)
1333{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001334 dprintk(1, "\n");
1335
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001336 return MPEGTSConfigurePins(state, false);
1337}
1338
1339static int BLChainCmd(struct drxk_state *state,
1340 u16 romOffset, u16 nrOfElements, u32 timeOut)
1341{
1342 u16 blStatus = 0;
1343 int status;
1344 unsigned long end;
1345
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001346 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001347 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001348 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1349 if (status < 0)
1350 goto error;
1351 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1352 if (status < 0)
1353 goto error;
1354 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1355 if (status < 0)
1356 goto error;
1357 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1358 if (status < 0)
1359 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001360
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001361 end = jiffies + msecs_to_jiffies(timeOut);
1362 do {
1363 msleep(1);
1364 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1365 if (status < 0)
1366 goto error;
1367 } while ((blStatus == 0x1) &&
1368 ((time_is_after_jiffies(end))));
1369
1370 if (blStatus == 0x1) {
1371 printk(KERN_ERR "drxk: SIO not ready\n");
1372 status = -EINVAL;
1373 goto error2;
1374 }
1375error:
1376 if (status < 0)
1377 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1378error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001379 mutex_unlock(&state->mutex);
1380 return status;
1381}
1382
1383
1384static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001385 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001386{
1387 const u8 *pSrc = pMCImage;
1388 u16 Flags;
1389 u16 Drain;
1390 u32 Address;
1391 u16 nBlocks;
1392 u16 BlockSize;
1393 u16 BlockCRC;
1394 u32 offset = 0;
1395 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001396 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001397
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001398 dprintk(1, "\n");
1399
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001400 /* down the drain (we don care about MAGIC_WORD) */
1401 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001402 pSrc += sizeof(u16);
1403 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001404 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001405 pSrc += sizeof(u16);
1406 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001407
1408 for (i = 0; i < nBlocks; i += 1) {
1409 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001410 (pSrc[2] << 8) | pSrc[3];
1411 pSrc += sizeof(u32);
1412 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001413
1414 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001415 pSrc += sizeof(u16);
1416 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001417
1418 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001419 pSrc += sizeof(u16);
1420 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001421
1422 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001423 pSrc += sizeof(u16);
1424 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001425
1426 if (offset + BlockSize > Length) {
1427 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1428 return -EINVAL;
1429 }
1430
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001431 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001432 if (status < 0) {
1433 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001434 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001435 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001436 pSrc += BlockSize;
1437 offset += BlockSize;
1438 }
1439 return status;
1440}
1441
1442static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1443{
1444 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001445 u16 data = 0;
1446 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001447 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1448 unsigned long end;
1449
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001450 dprintk(1, "\n");
1451
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001452 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001453 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001454 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1455 }
1456
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001457 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1458 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001459 /* tokenring already has correct status */
1460 return status;
1461 }
1462 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001463 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001464
Oliver Endrissebc7de22011-07-03 13:49:44 -03001465 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001466 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001467 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001468 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001469 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001470 msleep(1);
1471 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001472 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001473 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001474 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001475 }
1476 return status;
1477}
1478
1479static int MPEGTSStop(struct drxk_state *state)
1480{
1481 int status = 0;
1482 u16 fecOcSncMode = 0;
1483 u16 fecOcIprMode = 0;
1484
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001485 dprintk(1, "\n");
1486
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001487 /* Gracefull shutdown (byte boundaries) */
1488 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1489 if (status < 0)
1490 goto error;
1491 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1492 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1493 if (status < 0)
1494 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001495
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001496 /* Suppress MCLK during absence of data */
1497 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1498 if (status < 0)
1499 goto error;
1500 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1501 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1502
1503error:
1504 if (status < 0)
1505 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1506
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001507 return status;
1508}
1509
1510static int scu_command(struct drxk_state *state,
1511 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001512 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001513{
1514#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1515#error DRXK register mapping no longer compatible with this routine!
1516#endif
1517 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001518 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001519 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001520 u8 buffer[34];
1521 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001522 const char *p;
1523 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001524
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001525 dprintk(1, "\n");
1526
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001527 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1528 ((resultLen > 0) && (result == NULL)))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001529 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001530
1531 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001532
1533 /* assume that the command register is ready
1534 since it is checked afterwards */
1535 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1536 buffer[cnt++] = (parameter[ii] & 0xFF);
1537 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1538 }
1539 buffer[cnt++] = (cmd & 0xFF);
1540 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1541
1542 write_block(state, SCU_RAM_PARAM_0__A -
1543 (parameterLen - 1), cnt, buffer);
1544 /* Wait until SCU has processed command */
1545 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001546 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001547 msleep(1);
1548 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1549 if (status < 0)
1550 goto error;
1551 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1552 if (curCmd != DRX_SCU_READY) {
1553 printk(KERN_ERR "drxk: SCU not ready\n");
1554 status = -EIO;
1555 goto error2;
1556 }
1557 /* read results */
1558 if ((resultLen > 0) && (result != NULL)) {
1559 s16 err;
1560 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001561
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001562 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1563 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001564 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001565 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001566 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001567
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001568 /* Check if an error was reported by SCU */
1569 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001570 if (err >= 0)
1571 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001572
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001573 /* check for the known error codes */
1574 switch (err) {
1575 case SCU_RESULT_UNKCMD:
1576 p = "SCU_RESULT_UNKCMD";
1577 break;
1578 case SCU_RESULT_UNKSTD:
1579 p = "SCU_RESULT_UNKSTD";
1580 break;
1581 case SCU_RESULT_SIZE:
1582 p = "SCU_RESULT_SIZE";
1583 break;
1584 case SCU_RESULT_INVPAR:
1585 p = "SCU_RESULT_INVPAR";
1586 break;
1587 default: /* Other negative values are errors */
1588 sprintf(errname, "ERROR: %d\n", err);
1589 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001590 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001591 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1592 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1593 status = -EINVAL;
1594 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001595 }
1596
1597error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001598 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001599 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001600error2:
1601 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001602 return status;
1603}
1604
1605static int SetIqmAf(struct drxk_state *state, bool active)
1606{
1607 u16 data = 0;
1608 int status;
1609
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001610 dprintk(1, "\n");
1611
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001612 /* Configure IQM */
1613 status = read16(state, IQM_AF_STDBY__A, &data);
1614 if (status < 0)
1615 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001616
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001617 if (!active) {
1618 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1619 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1620 | IQM_AF_STDBY_STDBY_PD_STANDBY
1621 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1622 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1623 } else {
1624 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1625 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1626 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1627 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1628 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1629 );
1630 }
1631 status = write16(state, IQM_AF_STDBY__A, data);
1632
1633error:
1634 if (status < 0)
1635 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001636 return status;
1637}
1638
Oliver Endrissebc7de22011-07-03 13:49:44 -03001639static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001640{
1641 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001642 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001643
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001644 dprintk(1, "\n");
1645
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001646 /* Check arguments */
1647 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001648 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001649
1650 switch (*mode) {
1651 case DRX_POWER_UP:
1652 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1653 break;
1654 case DRXK_POWER_DOWN_OFDM:
1655 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1656 break;
1657 case DRXK_POWER_DOWN_CORE:
1658 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1659 break;
1660 case DRXK_POWER_DOWN_PLL:
1661 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1662 break;
1663 case DRX_POWER_DOWN:
1664 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1665 break;
1666 default:
1667 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001668 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001669 }
1670
1671 /* If already in requested power mode, do nothing */
1672 if (state->m_currentPowerMode == *mode)
1673 return 0;
1674
1675 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001676 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001677 status = PowerUpDevice(state);
1678 if (status < 0)
1679 goto error;
1680 status = DVBTEnableOFDMTokenRing(state, true);
1681 if (status < 0)
1682 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001683 }
1684
1685 if (*mode == DRX_POWER_UP) {
1686 /* Restore analog & pin configuartion */
1687 } else {
1688 /* Power down to requested mode */
1689 /* Backup some register settings */
1690 /* Set pins with possible pull-ups connected
1691 to them in input mode */
1692 /* Analog power down */
1693 /* ADC power down */
1694 /* Power down device */
1695 /* stop all comm_exec */
1696 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001697 switch (state->m_OperationMode) {
1698 case OM_DVBT:
1699 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001700 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001701 goto error;
1702 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001703 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001704 goto error;
1705 break;
1706 case OM_QAM_ITU_A:
1707 case OM_QAM_ITU_C:
1708 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001709 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001710 goto error;
1711 status = PowerDownQAM(state);
1712 if (status < 0)
1713 goto error;
1714 break;
1715 default:
1716 break;
1717 }
1718 status = DVBTEnableOFDMTokenRing(state, false);
1719 if (status < 0)
1720 goto error;
1721 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1722 if (status < 0)
1723 goto error;
1724 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1725 if (status < 0)
1726 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001727
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001728 if (*mode != DRXK_POWER_DOWN_OFDM) {
1729 state->m_HICfgCtrl |=
1730 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1731 status = HI_CfgCommand(state);
1732 if (status < 0)
1733 goto error;
1734 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001735 }
1736 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001737
1738error:
1739 if (status < 0)
1740 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1741
Oliver Endrissebc7de22011-07-03 13:49:44 -03001742 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001743}
1744
1745static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1746{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001747 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001748 u16 cmdResult = 0;
1749 u16 data = 0;
1750 int status;
1751
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001752 dprintk(1, "\n");
1753
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001754 status = read16(state, SCU_COMM_EXEC__A, &data);
1755 if (status < 0)
1756 goto error;
1757 if (data == SCU_COMM_EXEC_ACTIVE) {
1758 /* Send OFDM stop command */
1759 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 -03001760 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001761 goto error;
1762 /* Send OFDM reset command */
1763 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1764 if (status < 0)
1765 goto error;
1766 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001767
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001768 /* Reset datapath for OFDM, processors first */
1769 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1770 if (status < 0)
1771 goto error;
1772 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1773 if (status < 0)
1774 goto error;
1775 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1776 if (status < 0)
1777 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001778
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001779 /* powerdown AFE */
1780 status = SetIqmAf(state, false);
1781 if (status < 0)
1782 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001783
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001784 /* powerdown to OFDM mode */
1785 if (setPowerMode) {
1786 status = CtrlPowerMode(state, &powerMode);
1787 if (status < 0)
1788 goto error;
1789 }
1790error:
1791 if (status < 0)
1792 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001793 return status;
1794}
1795
Oliver Endrissebc7de22011-07-03 13:49:44 -03001796static int SetOperationMode(struct drxk_state *state,
1797 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001798{
1799 int status = 0;
1800
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001801 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001802 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001803 Stop and power down previous standard
1804 TODO investigate total power down instead of partial
1805 power down depending on "previous" standard.
1806 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001807
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001808 /* disable HW lock indicator */
1809 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1810 if (status < 0)
1811 goto error;
1812
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001813 /* Device is already at the required mode */
1814 if (state->m_OperationMode == oMode)
1815 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001816
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001817 switch (state->m_OperationMode) {
1818 /* OM_NONE was added for start up */
1819 case OM_NONE:
1820 break;
1821 case OM_DVBT:
1822 status = MPEGTSStop(state);
1823 if (status < 0)
1824 goto error;
1825 status = PowerDownDVBT(state, true);
1826 if (status < 0)
1827 goto error;
1828 state->m_OperationMode = OM_NONE;
1829 break;
1830 case OM_QAM_ITU_A: /* fallthrough */
1831 case OM_QAM_ITU_C:
1832 status = MPEGTSStop(state);
1833 if (status < 0)
1834 goto error;
1835 status = PowerDownQAM(state);
1836 if (status < 0)
1837 goto error;
1838 state->m_OperationMode = OM_NONE;
1839 break;
1840 case OM_QAM_ITU_B:
1841 default:
1842 status = -EINVAL;
1843 goto error;
1844 }
1845
1846 /*
1847 Power up new standard
1848 */
1849 switch (oMode) {
1850 case OM_DVBT:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001851 dprintk(1, ": DVB-T\n");
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001852 state->m_OperationMode = oMode;
1853 status = SetDVBTStandard(state, oMode);
1854 if (status < 0)
1855 goto error;
1856 break;
1857 case OM_QAM_ITU_A: /* fallthrough */
1858 case OM_QAM_ITU_C:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001859 dprintk(1, ": DVB-C Annex %c\n",
1860 (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001861 state->m_OperationMode = oMode;
1862 status = SetQAMStandard(state, oMode);
1863 if (status < 0)
1864 goto error;
1865 break;
1866 case OM_QAM_ITU_B:
1867 default:
1868 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001869 }
1870error:
1871 if (status < 0)
1872 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1873 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001874}
1875
1876static int Start(struct drxk_state *state, s32 offsetFreq,
1877 s32 IntermediateFrequency)
1878{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001879 int status = -EINVAL;
1880
1881 u16 IFreqkHz;
1882 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001883
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001884 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001885 if (state->m_DrxkState != DRXK_STOPPED &&
1886 state->m_DrxkState != DRXK_DTV_STARTED)
1887 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001888
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03001889 state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001890
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001891 if (IntermediateFrequency < 0) {
1892 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1893 IntermediateFrequency = -IntermediateFrequency;
1894 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001895
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001896 switch (state->m_OperationMode) {
1897 case OM_QAM_ITU_A:
1898 case OM_QAM_ITU_C:
1899 IFreqkHz = (IntermediateFrequency / 1000);
1900 status = SetQAM(state, IFreqkHz, OffsetkHz);
1901 if (status < 0)
1902 goto error;
1903 state->m_DrxkState = DRXK_DTV_STARTED;
1904 break;
1905 case OM_DVBT:
1906 IFreqkHz = (IntermediateFrequency / 1000);
1907 status = MPEGTSStop(state);
1908 if (status < 0)
1909 goto error;
1910 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1911 if (status < 0)
1912 goto error;
1913 status = DVBTStart(state);
1914 if (status < 0)
1915 goto error;
1916 state->m_DrxkState = DRXK_DTV_STARTED;
1917 break;
1918 default:
1919 break;
1920 }
1921error:
1922 if (status < 0)
1923 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001924 return status;
1925}
1926
1927static int ShutDown(struct drxk_state *state)
1928{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001929 dprintk(1, "\n");
1930
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001931 MPEGTSStop(state);
1932 return 0;
1933}
1934
Oliver Endrissebc7de22011-07-03 13:49:44 -03001935static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1936 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001937{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001938 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001939
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001940 dprintk(1, "\n");
1941
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001942 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001943 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001944
1945 *pLockStatus = NOT_LOCKED;
1946
1947 /* define the SCU command code */
1948 switch (state->m_OperationMode) {
1949 case OM_QAM_ITU_A:
1950 case OM_QAM_ITU_B:
1951 case OM_QAM_ITU_C:
1952 status = GetQAMLockStatus(state, pLockStatus);
1953 break;
1954 case OM_DVBT:
1955 status = GetDVBTLockStatus(state, pLockStatus);
1956 break;
1957 default:
1958 break;
1959 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001960error:
1961 if (status < 0)
1962 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001963 return status;
1964}
1965
1966static int MPEGTSStart(struct drxk_state *state)
1967{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001968 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001969
1970 u16 fecOcSncMode = 0;
1971
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001972 /* Allow OC to sync again */
1973 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1974 if (status < 0)
1975 goto error;
1976 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1977 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1978 if (status < 0)
1979 goto error;
1980 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1981error:
1982 if (status < 0)
1983 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001984 return status;
1985}
1986
1987static int MPEGTSDtoInit(struct drxk_state *state)
1988{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001989 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001990
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001991 dprintk(1, "\n");
1992
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001993 /* Rate integration settings */
1994 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1995 if (status < 0)
1996 goto error;
1997 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1998 if (status < 0)
1999 goto error;
2000 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
2001 if (status < 0)
2002 goto error;
2003 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
2004 if (status < 0)
2005 goto error;
2006 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2007 if (status < 0)
2008 goto error;
2009 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2010 if (status < 0)
2011 goto error;
2012 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2013 if (status < 0)
2014 goto error;
2015 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2016 if (status < 0)
2017 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002018
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002019 /* Additional configuration */
2020 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2021 if (status < 0)
2022 goto error;
2023 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2024 if (status < 0)
2025 goto error;
2026 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2027error:
2028 if (status < 0)
2029 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2030
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002031 return status;
2032}
2033
Oliver Endrissebc7de22011-07-03 13:49:44 -03002034static int MPEGTSDtoSetup(struct drxk_state *state,
2035 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002036{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002037 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002038
Oliver Endrissebc7de22011-07-03 13:49:44 -03002039 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2040 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2041 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2042 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2043 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2044 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2045 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002046 u16 fecOcTmdMode = 0;
2047 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002048 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002049 bool staticCLK = false;
2050
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002051 dprintk(1, "\n");
2052
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002053 /* Check insertion of the Reed-Solomon parity bytes */
2054 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2055 if (status < 0)
2056 goto error;
2057 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2058 if (status < 0)
2059 goto error;
2060 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2061 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2062 if (state->m_insertRSByte == true) {
2063 /* enable parity symbol forward */
2064 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2065 /* MVAL disable during parity bytes */
2066 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2067 /* TS burst length to 204 */
2068 fecOcDtoBurstLen = 204;
2069 }
2070
2071 /* Check serial or parrallel output */
2072 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2073 if (state->m_enableParallel == false) {
2074 /* MPEG data output is serial -> set ipr_mode[0] */
2075 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2076 }
2077
2078 switch (oMode) {
2079 case OM_DVBT:
2080 maxBitRate = state->m_DVBTBitrate;
2081 fecOcTmdMode = 3;
2082 fecOcRcnCtlRate = 0xC00000;
2083 staticCLK = state->m_DVBTStaticCLK;
2084 break;
2085 case OM_QAM_ITU_A: /* fallthrough */
2086 case OM_QAM_ITU_C:
2087 fecOcTmdMode = 0x0004;
2088 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2089 maxBitRate = state->m_DVBCBitrate;
2090 staticCLK = state->m_DVBCStaticCLK;
2091 break;
2092 default:
2093 status = -EINVAL;
2094 } /* switch (standard) */
2095 if (status < 0)
2096 goto error;
2097
2098 /* Configure DTO's */
2099 if (staticCLK) {
2100 u32 bitRate = 0;
2101
2102 /* Rational DTO for MCLK source (static MCLK rate),
2103 Dynamic DTO for optimal grouping
2104 (avoid intra-packet gaps),
2105 DTO offset enable to sync TS burst with MSTRT */
2106 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2107 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2108 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2109 FEC_OC_FCT_MODE_VIRT_ENA__M);
2110
2111 /* Check user defined bitrate */
2112 bitRate = maxBitRate;
2113 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2114 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002115 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002116 /* Rational DTO period:
2117 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002118
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002119 Result should be floored,
2120 to make sure >= requested bitrate
2121 */
2122 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2123 * 1000) / bitRate);
2124 if (fecOcDtoPeriod <= 2)
2125 fecOcDtoPeriod = 0;
2126 else
2127 fecOcDtoPeriod -= 2;
2128 fecOcTmdIntUpdRate = 8;
2129 } else {
2130 /* (commonAttr->staticCLK == false) => dynamic mode */
2131 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2132 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2133 fecOcTmdIntUpdRate = 5;
2134 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002135
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002136 /* Write appropriate registers with requested configuration */
2137 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2138 if (status < 0)
2139 goto error;
2140 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2141 if (status < 0)
2142 goto error;
2143 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2144 if (status < 0)
2145 goto error;
2146 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2147 if (status < 0)
2148 goto error;
2149 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2150 if (status < 0)
2151 goto error;
2152 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2153 if (status < 0)
2154 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002155
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002156 /* Rate integration settings */
2157 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2158 if (status < 0)
2159 goto error;
2160 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2161 if (status < 0)
2162 goto error;
2163 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2164error:
2165 if (status < 0)
2166 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002167 return status;
2168}
2169
2170static int MPEGTSConfigurePolarity(struct drxk_state *state)
2171{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002172 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002173
2174 /* Data mask for the output data byte */
2175 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002176 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2177 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2178 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2179 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002180
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002181 dprintk(1, "\n");
2182
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002183 /* Control selective inversion of output bits */
2184 fecOcRegIprInvert &= (~(InvertDataMask));
2185 if (state->m_invertDATA == true)
2186 fecOcRegIprInvert |= InvertDataMask;
2187 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2188 if (state->m_invertERR == true)
2189 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2190 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2191 if (state->m_invertSTR == true)
2192 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2193 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2194 if (state->m_invertVAL == true)
2195 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2196 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2197 if (state->m_invertCLK == true)
2198 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002199
2200 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002201}
2202
2203#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2204
2205static int SetAgcRf(struct drxk_state *state,
2206 struct SCfgAgc *pAgcCfg, bool isDTV)
2207{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002208 int status = -EINVAL;
2209 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002210 struct SCfgAgc *pIfAgcSettings;
2211
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002212 dprintk(1, "\n");
2213
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002214 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002215 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002216
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002217 switch (pAgcCfg->ctrlMode) {
2218 case DRXK_AGC_CTRL_AUTO:
2219 /* Enable RF AGC DAC */
2220 status = read16(state, IQM_AF_STDBY__A, &data);
2221 if (status < 0)
2222 goto error;
2223 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2224 status = write16(state, IQM_AF_STDBY__A, data);
2225 if (status < 0)
2226 goto error;
2227 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2228 if (status < 0)
2229 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002230
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002231 /* Enable SCU RF AGC loop */
2232 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002233
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002234 /* Polarity */
2235 if (state->m_RfAgcPol)
2236 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2237 else
2238 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2239 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2240 if (status < 0)
2241 goto error;
2242
2243 /* Set speed (using complementary reduction value) */
2244 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2245 if (status < 0)
2246 goto error;
2247
2248 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2249 data |= (~(pAgcCfg->speed <<
2250 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2251 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2252
2253 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2254 if (status < 0)
2255 goto error;
2256
2257 if (IsDVBT(state))
2258 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2259 else if (IsQAM(state))
2260 pIfAgcSettings = &state->m_qamIfAgcCfg;
2261 else
2262 pIfAgcSettings = &state->m_atvIfAgcCfg;
2263 if (pIfAgcSettings == NULL) {
2264 status = -EINVAL;
2265 goto error;
2266 }
2267
2268 /* Set TOP, only if IF-AGC is in AUTO mode */
2269 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2270 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002271 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002272 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002273
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002274 /* Cut-Off current */
2275 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2276 if (status < 0)
2277 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002278
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002279 /* Max. output level */
2280 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2281 if (status < 0)
2282 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002283
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002284 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002285
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002286 case DRXK_AGC_CTRL_USER:
2287 /* Enable RF AGC DAC */
2288 status = read16(state, IQM_AF_STDBY__A, &data);
2289 if (status < 0)
2290 goto error;
2291 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2292 status = write16(state, IQM_AF_STDBY__A, data);
2293 if (status < 0)
2294 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002295
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002296 /* Disable SCU RF AGC loop */
2297 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2298 if (status < 0)
2299 goto error;
2300 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2301 if (state->m_RfAgcPol)
2302 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2303 else
2304 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2305 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2306 if (status < 0)
2307 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002308
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002309 /* SCU c.o.c. to 0, enabling full control range */
2310 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2311 if (status < 0)
2312 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002313
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002314 /* Write value to output pin */
2315 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2316 if (status < 0)
2317 goto error;
2318 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002319
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002320 case DRXK_AGC_CTRL_OFF:
2321 /* Disable RF AGC DAC */
2322 status = read16(state, IQM_AF_STDBY__A, &data);
2323 if (status < 0)
2324 goto error;
2325 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2326 status = write16(state, IQM_AF_STDBY__A, data);
2327 if (status < 0)
2328 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002329
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002330 /* Disable SCU RF AGC loop */
2331 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2332 if (status < 0)
2333 goto error;
2334 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2335 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2336 if (status < 0)
2337 goto error;
2338 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002339
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002340 default:
2341 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002342
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002343 }
2344error:
2345 if (status < 0)
2346 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002347 return status;
2348}
2349
2350#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2351
Oliver Endrissebc7de22011-07-03 13:49:44 -03002352static int SetAgcIf(struct drxk_state *state,
2353 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002354{
2355 u16 data = 0;
2356 int status = 0;
2357 struct SCfgAgc *pRfAgcSettings;
2358
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002359 dprintk(1, "\n");
2360
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002361 switch (pAgcCfg->ctrlMode) {
2362 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002363
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002364 /* Enable IF AGC DAC */
2365 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002366 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002367 goto error;
2368 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2369 status = write16(state, IQM_AF_STDBY__A, data);
2370 if (status < 0)
2371 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002372
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002373 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2374 if (status < 0)
2375 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002376
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002377 /* Enable SCU IF AGC loop */
2378 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2379
2380 /* Polarity */
2381 if (state->m_IfAgcPol)
2382 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2383 else
2384 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2385 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2386 if (status < 0)
2387 goto error;
2388
2389 /* Set speed (using complementary reduction value) */
2390 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2391 if (status < 0)
2392 goto error;
2393 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2394 data |= (~(pAgcCfg->speed <<
2395 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2396 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2397
2398 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2399 if (status < 0)
2400 goto error;
2401
2402 if (IsQAM(state))
2403 pRfAgcSettings = &state->m_qamRfAgcCfg;
2404 else
2405 pRfAgcSettings = &state->m_atvRfAgcCfg;
2406 if (pRfAgcSettings == NULL)
2407 return -1;
2408 /* Restore TOP */
2409 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2410 if (status < 0)
2411 goto error;
2412 break;
2413
2414 case DRXK_AGC_CTRL_USER:
2415
2416 /* Enable IF AGC DAC */
2417 status = read16(state, IQM_AF_STDBY__A, &data);
2418 if (status < 0)
2419 goto error;
2420 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2421 status = write16(state, IQM_AF_STDBY__A, data);
2422 if (status < 0)
2423 goto error;
2424
2425 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2426 if (status < 0)
2427 goto error;
2428
2429 /* Disable SCU IF AGC loop */
2430 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2431
2432 /* Polarity */
2433 if (state->m_IfAgcPol)
2434 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2435 else
2436 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2437 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2438 if (status < 0)
2439 goto error;
2440
2441 /* Write value to output pin */
2442 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2443 if (status < 0)
2444 goto error;
2445 break;
2446
2447 case DRXK_AGC_CTRL_OFF:
2448
2449 /* Disable If AGC DAC */
2450 status = read16(state, IQM_AF_STDBY__A, &data);
2451 if (status < 0)
2452 goto error;
2453 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2454 status = write16(state, IQM_AF_STDBY__A, data);
2455 if (status < 0)
2456 goto error;
2457
2458 /* Disable SCU IF AGC loop */
2459 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2460 if (status < 0)
2461 goto error;
2462 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2463 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2464 if (status < 0)
2465 goto error;
2466 break;
2467 } /* switch (agcSettingsIf->ctrlMode) */
2468
2469 /* always set the top to support
2470 configurations without if-loop */
2471 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2472error:
2473 if (status < 0)
2474 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002475 return status;
2476}
2477
2478static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2479{
2480 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002481 int status;
2482 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002483
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002484 dprintk(1, "\n");
2485
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002486 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2487 if (status < 0) {
2488 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2489 return status;
2490 }
2491
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002492 *pValue = 0;
2493
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002494 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2495 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2496 if (Level < 14000)
2497 *pValue = (14000 - Level) / 4;
2498 else
2499 *pValue = 0;
2500
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002501 return status;
2502}
2503
Oliver Endrissebc7de22011-07-03 13:49:44 -03002504static int GetQAMSignalToNoise(struct drxk_state *state,
2505 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002506{
2507 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002508 u16 qamSlErrPower = 0; /* accum. error between
2509 raw and sliced symbols */
2510 u32 qamSlSigPower = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002511 QAM modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002512 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002513
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002514 dprintk(1, "\n");
2515
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002516 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002517
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002518 /* get the register value needed for MER */
2519 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2520 if (status < 0) {
2521 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2522 return -EINVAL;
2523 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002524
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002525 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002526 case QAM_16:
2527 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2528 break;
2529 case QAM_32:
2530 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2531 break;
2532 case QAM_64:
2533 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2534 break;
2535 case QAM_128:
2536 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2537 break;
2538 default:
2539 case QAM_256:
2540 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2541 break;
2542 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002543
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002544 if (qamSlErrPower > 0) {
2545 qamSlMer = Log10Times100(qamSlSigPower) -
2546 Log10Times100((u32) qamSlErrPower);
2547 }
2548 *pSignalToNoise = qamSlMer;
2549
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002550 return status;
2551}
2552
Oliver Endrissebc7de22011-07-03 13:49:44 -03002553static int GetDVBTSignalToNoise(struct drxk_state *state,
2554 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002555{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002556 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002557 u16 regData = 0;
2558 u32 EqRegTdSqrErrI = 0;
2559 u32 EqRegTdSqrErrQ = 0;
2560 u16 EqRegTdSqrErrExp = 0;
2561 u16 EqRegTdTpsPwrOfs = 0;
2562 u16 EqRegTdReqSmbCnt = 0;
2563 u32 tpsCnt = 0;
2564 u32 SqrErrIQ = 0;
2565 u32 a = 0;
2566 u32 b = 0;
2567 u32 c = 0;
2568 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002569 u16 transmissionParams = 0;
2570
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002571 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002572
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002573 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2574 if (status < 0)
2575 goto error;
2576 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2577 if (status < 0)
2578 goto error;
2579 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2580 if (status < 0)
2581 goto error;
2582 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2583 if (status < 0)
2584 goto error;
2585 /* Extend SQR_ERR_I operational range */
2586 EqRegTdSqrErrI = (u32) regData;
2587 if ((EqRegTdSqrErrExp > 11) &&
2588 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2589 EqRegTdSqrErrI += 0x00010000UL;
2590 }
2591 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2592 if (status < 0)
2593 goto error;
2594 /* Extend SQR_ERR_Q operational range */
2595 EqRegTdSqrErrQ = (u32) regData;
2596 if ((EqRegTdSqrErrExp > 11) &&
2597 (EqRegTdSqrErrQ < 0x00000FFFUL))
2598 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002599
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002600 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2601 if (status < 0)
2602 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002603
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002604 /* Check input data for MER */
2605
2606 /* MER calculation (in 0.1 dB) without math.h */
2607 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2608 iMER = 0;
2609 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2610 /* No error at all, this must be the HW reset value
2611 * Apparently no first measurement yet
2612 * Set MER to 0.0 */
2613 iMER = 0;
2614 } else {
2615 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2616 EqRegTdSqrErrExp;
2617 if ((transmissionParams &
2618 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2619 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2620 tpsCnt = 17;
2621 else
2622 tpsCnt = 68;
2623
2624 /* IMER = 100 * log10 (x)
2625 where x = (EqRegTdTpsPwrOfs^2 *
2626 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2627
2628 => IMER = a + b -c
2629 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2630 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2631 c = 100 * log10 (SqrErrIQ)
2632 */
2633
2634 /* log(x) x = 9bits * 9bits->18 bits */
2635 a = Log10Times100(EqRegTdTpsPwrOfs *
2636 EqRegTdTpsPwrOfs);
2637 /* log(x) x = 16bits * 7bits->23 bits */
2638 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2639 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2640 c = Log10Times100(SqrErrIQ);
2641
2642 iMER = a + b;
2643 /* No negative MER, clip to zero */
2644 if (iMER > c)
2645 iMER -= c;
2646 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002647 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002648 }
2649 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002650
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002651error:
2652 if (status < 0)
2653 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002654 return status;
2655}
2656
2657static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2658{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002659 dprintk(1, "\n");
2660
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002661 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002662 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002663 case OM_DVBT:
2664 return GetDVBTSignalToNoise(state, pSignalToNoise);
2665 case OM_QAM_ITU_A:
2666 case OM_QAM_ITU_C:
2667 return GetQAMSignalToNoise(state, pSignalToNoise);
2668 default:
2669 break;
2670 }
2671 return 0;
2672}
2673
2674#if 0
2675static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2676{
2677 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2678 int status = 0;
2679
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002680 dprintk(1, "\n");
2681
Oliver Endrissebc7de22011-07-03 13:49:44 -03002682 static s32 QE_SN[] = {
2683 51, /* QPSK 1/2 */
2684 69, /* QPSK 2/3 */
2685 79, /* QPSK 3/4 */
2686 89, /* QPSK 5/6 */
2687 97, /* QPSK 7/8 */
2688 108, /* 16-QAM 1/2 */
2689 131, /* 16-QAM 2/3 */
2690 146, /* 16-QAM 3/4 */
2691 156, /* 16-QAM 5/6 */
2692 160, /* 16-QAM 7/8 */
2693 165, /* 64-QAM 1/2 */
2694 187, /* 64-QAM 2/3 */
2695 202, /* 64-QAM 3/4 */
2696 216, /* 64-QAM 5/6 */
2697 225, /* 64-QAM 7/8 */
2698 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002699
2700 *pQuality = 0;
2701
2702 do {
2703 s32 SignalToNoise = 0;
2704 u16 Constellation = 0;
2705 u16 CodeRate = 0;
2706 u32 SignalToNoiseRel;
2707 u32 BERQuality;
2708
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002709 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2710 if (status < 0)
2711 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002712 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002713 if (status < 0)
2714 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002715 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2716
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002717 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002718 if (status < 0)
2719 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002720 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2721
2722 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2723 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2724 break;
2725 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002726 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002727 BERQuality = 100;
2728
Oliver Endrissebc7de22011-07-03 13:49:44 -03002729 if (SignalToNoiseRel < -70)
2730 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002731 else if (SignalToNoiseRel < 30)
2732 *pQuality = ((SignalToNoiseRel + 70) *
2733 BERQuality) / 100;
2734 else
2735 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002736 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002737 return 0;
2738};
2739
Oliver Endrissebc7de22011-07-03 13:49:44 -03002740static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002741{
2742 int status = 0;
2743 *pQuality = 0;
2744
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002745 dprintk(1, "\n");
2746
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002747 do {
2748 u32 SignalToNoise = 0;
2749 u32 BERQuality = 100;
2750 u32 SignalToNoiseRel = 0;
2751
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002752 status = GetQAMSignalToNoise(state, &SignalToNoise);
2753 if (status < 0)
2754 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002755
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002756 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002757 case QAM_16:
2758 SignalToNoiseRel = SignalToNoise - 200;
2759 break;
2760 case QAM_32:
2761 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002762 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002763 case QAM_64:
2764 SignalToNoiseRel = SignalToNoise - 260;
2765 break;
2766 case QAM_128:
2767 SignalToNoiseRel = SignalToNoise - 290;
2768 break;
2769 default:
2770 case QAM_256:
2771 SignalToNoiseRel = SignalToNoise - 320;
2772 break;
2773 }
2774
2775 if (SignalToNoiseRel < -70)
2776 *pQuality = 0;
2777 else if (SignalToNoiseRel < 30)
2778 *pQuality = ((SignalToNoiseRel + 70) *
2779 BERQuality) / 100;
2780 else
2781 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002782 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002783
2784 return status;
2785}
2786
2787static int GetQuality(struct drxk_state *state, s32 *pQuality)
2788{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002789 dprintk(1, "\n");
2790
Oliver Endrissebc7de22011-07-03 13:49:44 -03002791 switch (state->m_OperationMode) {
2792 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002793 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002794 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002795 return GetDVBCQuality(state, pQuality);
2796 default:
2797 break;
2798 }
2799
2800 return 0;
2801}
2802#endif
2803
2804/* Free data ram in SIO HI */
2805#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2806#define SIO_HI_RA_RAM_USR_END__A 0x420060
2807
2808#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2809#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2810#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2811#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2812
2813#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2814#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2815#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2816
2817static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2818{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002819 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002820
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002821 dprintk(1, "\n");
2822
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002823 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002824 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002825 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002826 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002827
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002828 if (state->no_i2c_bridge)
2829 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002830
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002831 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2832 if (status < 0)
2833 goto error;
2834 if (bEnableBridge) {
2835 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 -03002836 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002837 goto error;
2838 } else {
2839 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2840 if (status < 0)
2841 goto error;
2842 }
2843
2844 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2845
2846error:
2847 if (status < 0)
2848 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002849 return status;
2850}
2851
Oliver Endrissebc7de22011-07-03 13:49:44 -03002852static int SetPreSaw(struct drxk_state *state,
2853 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002854{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002855 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002856
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002857 dprintk(1, "\n");
2858
Oliver Endrissebc7de22011-07-03 13:49:44 -03002859 if ((pPreSawCfg == NULL)
2860 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002861 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002862
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002863 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002864error:
2865 if (status < 0)
2866 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002867 return status;
2868}
2869
2870static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002871 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002872{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002873 u16 blStatus = 0;
2874 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2875 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2876 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002877 unsigned long end;
2878
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002879 dprintk(1, "\n");
2880
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002881 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002882 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2883 if (status < 0)
2884 goto error;
2885 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2886 if (status < 0)
2887 goto error;
2888 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2889 if (status < 0)
2890 goto error;
2891 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2892 if (status < 0)
2893 goto error;
2894 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2895 if (status < 0)
2896 goto error;
2897 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2898 if (status < 0)
2899 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002900
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002901 end = jiffies + msecs_to_jiffies(timeOut);
2902 do {
2903 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2904 if (status < 0)
2905 goto error;
2906 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2907 if (blStatus == 0x1) {
2908 printk(KERN_ERR "drxk: SIO not ready\n");
2909 status = -EINVAL;
2910 goto error2;
2911 }
2912error:
2913 if (status < 0)
2914 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2915error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002916 mutex_unlock(&state->mutex);
2917 return status;
2918
2919}
2920
Oliver Endrissebc7de22011-07-03 13:49:44 -03002921static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002922{
2923 u16 data = 0;
2924 int status;
2925
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002926 dprintk(1, "\n");
2927
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002928 /* Start measurement */
2929 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2930 if (status < 0)
2931 goto error;
2932 status = write16(state, IQM_AF_START_LOCK__A, 1);
2933 if (status < 0)
2934 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002935
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002936 *count = 0;
2937 status = read16(state, IQM_AF_PHASE0__A, &data);
2938 if (status < 0)
2939 goto error;
2940 if (data == 127)
2941 *count = *count + 1;
2942 status = read16(state, IQM_AF_PHASE1__A, &data);
2943 if (status < 0)
2944 goto error;
2945 if (data == 127)
2946 *count = *count + 1;
2947 status = read16(state, IQM_AF_PHASE2__A, &data);
2948 if (status < 0)
2949 goto error;
2950 if (data == 127)
2951 *count = *count + 1;
2952
2953error:
2954 if (status < 0)
2955 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002956 return status;
2957}
2958
2959static int ADCSynchronization(struct drxk_state *state)
2960{
2961 u16 count = 0;
2962 int status;
2963
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002964 dprintk(1, "\n");
2965
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002966 status = ADCSyncMeasurement(state, &count);
2967 if (status < 0)
2968 goto error;
2969
2970 if (count == 1) {
2971 /* Try sampling on a diffrent edge */
2972 u16 clkNeg = 0;
2973
2974 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2975 if (status < 0)
2976 goto error;
2977 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2978 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2979 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2980 clkNeg |=
2981 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2982 } else {
2983 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2984 clkNeg |=
2985 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2986 }
2987 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2988 if (status < 0)
2989 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002990 status = ADCSyncMeasurement(state, &count);
2991 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002992 goto error;
2993 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002994
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002995 if (count < 2)
2996 status = -EINVAL;
2997error:
2998 if (status < 0)
2999 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003000 return status;
3001}
3002
3003static int SetFrequencyShifter(struct drxk_state *state,
3004 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003005 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003006{
3007 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003008 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003009 u32 fmFrequencyShift = 0;
3010 bool tunerMirror = !state->m_bMirrorFreqSpect;
3011 u32 adcFreq;
3012 bool adcFlip;
3013 int status;
3014 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003015 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003016 u32 frequencyShift;
3017 bool imageToSelect;
3018
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003019 dprintk(1, "\n");
3020
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003021 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003022 Program frequency shifter
3023 No need to account for mirroring on RF
3024 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003025 if (isDTV) {
3026 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3027 (state->m_OperationMode == OM_QAM_ITU_C) ||
3028 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003029 selectPosImage = true;
3030 else
3031 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003032 }
3033 if (tunerMirror)
3034 /* tuner doesn't mirror */
3035 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003036 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003037 else
3038 /* tuner mirrors */
3039 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003040 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003041 if (ifFreqActual > samplingFrequency / 2) {
3042 /* adc mirrors */
3043 adcFreq = samplingFrequency - ifFreqActual;
3044 adcFlip = true;
3045 } else {
3046 /* adc doesn't mirror */
3047 adcFreq = ifFreqActual;
3048 adcFlip = false;
3049 }
3050
3051 frequencyShift = adcFreq;
3052 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003053 adcFlip ^ selectPosImage;
3054 state->m_IqmFsRateOfs =
3055 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003056
3057 if (imageToSelect)
3058 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3059
3060 /* Program frequency shifter with tuner offset compensation */
3061 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003062 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3063 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003064 if (status < 0)
3065 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003066 return status;
3067}
3068
3069static int InitAGC(struct drxk_state *state, bool isDTV)
3070{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003071 u16 ingainTgt = 0;
3072 u16 ingainTgtMin = 0;
3073 u16 ingainTgtMax = 0;
3074 u16 clpCyclen = 0;
3075 u16 clpSumMin = 0;
3076 u16 clpDirTo = 0;
3077 u16 snsSumMin = 0;
3078 u16 snsSumMax = 0;
3079 u16 clpSumMax = 0;
3080 u16 snsDirTo = 0;
3081 u16 kiInnergainMin = 0;
3082 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003083 u16 ifIaccuHiTgtMin = 0;
3084 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003085 u16 data = 0;
3086 u16 fastClpCtrlDelay = 0;
3087 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003088 int status = 0;
3089
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003090 dprintk(1, "\n");
3091
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003092 /* Common settings */
3093 snsSumMax = 1023;
3094 ifIaccuHiTgtMin = 2047;
3095 clpCyclen = 500;
3096 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003097
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003098 /* AGCInit() not available for DVBT; init done in microcode */
3099 if (!IsQAM(state)) {
3100 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3101 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003102 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003103
3104 /* FIXME: Analog TV AGC require different settings */
3105
3106 /* Standard specific settings */
3107 clpSumMin = 8;
3108 clpDirTo = (u16) -9;
3109 clpCtrlMode = 0;
3110 snsSumMin = 8;
3111 snsDirTo = (u16) -9;
3112 kiInnergainMin = (u16) -1030;
3113 ifIaccuHiTgtMax = 0x2380;
3114 ifIaccuHiTgt = 0x2380;
3115 ingainTgtMin = 0x0511;
3116 ingainTgt = 0x0511;
3117 ingainTgtMax = 5119;
3118 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3119
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003120 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3121 if (status < 0)
3122 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003123
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003124 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3125 if (status < 0)
3126 goto error;
3127 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3128 if (status < 0)
3129 goto error;
3130 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3131 if (status < 0)
3132 goto error;
3133 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3134 if (status < 0)
3135 goto error;
3136 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3137 if (status < 0)
3138 goto error;
3139 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3140 if (status < 0)
3141 goto error;
3142 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3143 if (status < 0)
3144 goto error;
3145 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3146 if (status < 0)
3147 goto error;
3148 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3149 if (status < 0)
3150 goto error;
3151 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3152 if (status < 0)
3153 goto error;
3154 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3155 if (status < 0)
3156 goto error;
3157 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
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_KI_INNERGAIN_MIN__A, kiInnergainMin);
3162 if (status < 0)
3163 goto error;
3164 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3165 if (status < 0)
3166 goto error;
3167 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
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_RF_SNS_DEV_MAX__A, 1023);
3172 if (status < 0)
3173 goto error;
3174 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3175 if (status < 0)
3176 goto error;
3177 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3178 if (status < 0)
3179 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003180
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003181 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3182 if (status < 0)
3183 goto error;
3184 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3185 if (status < 0)
3186 goto error;
3187 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3188 if (status < 0)
3189 goto error;
3190 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3191 if (status < 0)
3192 goto error;
3193 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3194 if (status < 0)
3195 goto error;
3196 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3197 if (status < 0)
3198 goto error;
3199 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3200 if (status < 0)
3201 goto error;
3202 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3203 if (status < 0)
3204 goto error;
3205 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3206 if (status < 0)
3207 goto error;
3208 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3209 if (status < 0)
3210 goto error;
3211 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3212 if (status < 0)
3213 goto error;
3214 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3215 if (status < 0)
3216 goto error;
3217 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3218 if (status < 0)
3219 goto error;
3220 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3221 if (status < 0)
3222 goto error;
3223 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3224 if (status < 0)
3225 goto error;
3226 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3227 if (status < 0)
3228 goto error;
3229 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3230 if (status < 0)
3231 goto error;
3232 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3233 if (status < 0)
3234 goto error;
3235 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3236 if (status < 0)
3237 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003238
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003239 /* Initialize inner-loop KI gain factors */
3240 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3241 if (status < 0)
3242 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003243
3244 data = 0x0657;
3245 data &= ~SCU_RAM_AGC_KI_RF__M;
3246 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3247 data &= ~SCU_RAM_AGC_KI_IF__M;
3248 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3249
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003250 status = write16(state, SCU_RAM_AGC_KI__A, data);
3251error:
3252 if (status < 0)
3253 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003254 return status;
3255}
3256
Oliver Endrissebc7de22011-07-03 13:49:44 -03003257static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003258{
3259 int status;
3260
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003261 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003262 if (packetErr == NULL)
3263 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3264 else
3265 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3266 if (status < 0)
3267 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003268 return status;
3269}
3270
3271static int DVBTScCommand(struct drxk_state *state,
3272 u16 cmd, u16 subcmd,
3273 u16 param0, u16 param1, u16 param2,
3274 u16 param3, u16 param4)
3275{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003276 u16 curCmd = 0;
3277 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003278 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003279 u16 scExec = 0;
3280 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003281
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003282 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003283 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003284 if (scExec != 1) {
3285 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003286 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003287 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003288 if (status < 0)
3289 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003290
3291 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003292 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003293 do {
3294 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003295 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003296 retryCnt++;
3297 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003298 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3299 goto error;
3300
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003301 /* Write sub-command */
3302 switch (cmd) {
3303 /* All commands using sub-cmd */
3304 case OFDM_SC_RA_RAM_CMD_PROC_START:
3305 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3306 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003307 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3308 if (status < 0)
3309 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003310 break;
3311 default:
3312 /* Do nothing */
3313 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003314 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003315
3316 /* Write needed parameters and the command */
3317 switch (cmd) {
3318 /* All commands using 5 parameters */
3319 /* All commands using 4 parameters */
3320 /* All commands using 3 parameters */
3321 /* All commands using 2 parameters */
3322 case OFDM_SC_RA_RAM_CMD_PROC_START:
3323 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3324 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003325 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003326 /* All commands using 1 parameters */
3327 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3328 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003329 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003330 /* All commands using 0 parameters */
3331 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3332 case OFDM_SC_RA_RAM_CMD_NULL:
3333 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003334 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003335 break;
3336 default:
3337 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003338 status = -EINVAL;
3339 }
3340 if (status < 0)
3341 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003342
3343 /* Wait until sc is ready processing command */
3344 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003345 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003346 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003347 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003348 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003349 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003350 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3351 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003352
3353 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003354 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003355 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003356 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003357 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003358 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003359 if (status < 0)
3360 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003361
3362 /* Retreive results parameters from SC */
3363 switch (cmd) {
3364 /* All commands yielding 5 results */
3365 /* All commands yielding 4 results */
3366 /* All commands yielding 3 results */
3367 /* All commands yielding 2 results */
3368 /* All commands yielding 1 result */
3369 case OFDM_SC_RA_RAM_CMD_USER_IO:
3370 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003371 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003372 /* All commands yielding 0 results */
3373 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3374 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3375 case OFDM_SC_RA_RAM_CMD_PROC_START:
3376 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3377 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3378 case OFDM_SC_RA_RAM_CMD_NULL:
3379 break;
3380 default:
3381 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003382 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003383 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003384 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003385error:
3386 if (status < 0)
3387 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003388 return status;
3389}
3390
Oliver Endrissebc7de22011-07-03 13:49:44 -03003391static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003392{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003393 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003394 int status;
3395
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003396 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003397 status = CtrlPowerMode(state, &powerMode);
3398 if (status < 0)
3399 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003400 return status;
3401}
3402
Oliver Endrissebc7de22011-07-03 13:49:44 -03003403static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003404{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003405 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003406
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003407 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003408 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003409 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003410 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003411 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003412 if (status < 0)
3413 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003414 return status;
3415}
3416
3417#define DEFAULT_FR_THRES_8K 4000
3418static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3419{
3420
3421 int status;
3422
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003423 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003424 if (*enabled == true) {
3425 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003426 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003427 DEFAULT_FR_THRES_8K);
3428 } else {
3429 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003430 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003431 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003432 if (status < 0)
3433 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003434
3435 return status;
3436}
3437
3438static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3439 struct DRXKCfgDvbtEchoThres_t *echoThres)
3440{
3441 u16 data = 0;
3442 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003443
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003444 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003445 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3446 if (status < 0)
3447 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003448
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003449 switch (echoThres->fftMode) {
3450 case DRX_FFTMODE_2K:
3451 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3452 data |= ((echoThres->threshold <<
3453 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3454 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003455 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003456 case DRX_FFTMODE_8K:
3457 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3458 data |= ((echoThres->threshold <<
3459 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3460 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003461 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003462 default:
3463 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003464 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003465
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003466 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3467error:
3468 if (status < 0)
3469 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003470 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003471}
3472
3473static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003474 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003475{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003476 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003477
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003478 dprintk(1, "\n");
3479
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003480 switch (*speed) {
3481 case DRXK_DVBT_SQI_SPEED_FAST:
3482 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3483 case DRXK_DVBT_SQI_SPEED_SLOW:
3484 break;
3485 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003486 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003487 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003488 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003489 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003490error:
3491 if (status < 0)
3492 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003493 return status;
3494}
3495
3496/*============================================================================*/
3497
3498/**
3499* \brief Activate DVBT specific presets
3500* \param demod instance of demodulator.
3501* \return DRXStatus_t.
3502*
3503* Called in DVBTSetStandard
3504*
3505*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003506static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003507{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003508 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003509 bool setincenable = false;
3510 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003511
Oliver Endrissebc7de22011-07-03 13:49:44 -03003512 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3513 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003514
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003515 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003516 status = DVBTCtrlSetIncEnable(state, &setincenable);
3517 if (status < 0)
3518 goto error;
3519 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3520 if (status < 0)
3521 goto error;
3522 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3523 if (status < 0)
3524 goto error;
3525 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3526 if (status < 0)
3527 goto error;
3528 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3529error:
3530 if (status < 0)
3531 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003532 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003533}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003534
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003535/*============================================================================*/
3536
3537/**
3538* \brief Initialize channelswitch-independent settings for DVBT.
3539* \param demod instance of demodulator.
3540* \return DRXStatus_t.
3541*
3542* For ROM code channel filter taps are loaded from the bootloader. For microcode
3543* the DVB-T taps from the drxk_filters.h are used.
3544*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003545static int SetDVBTStandard(struct drxk_state *state,
3546 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003547{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003548 u16 cmdResult = 0;
3549 u16 data = 0;
3550 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003551
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003552 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003553
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003554 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003555 /* added antenna switch */
3556 SwitchAntennaToDVBT(state);
3557 /* send OFDM reset command */
3558 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003559 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003560 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003561
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003562 /* send OFDM setenv command */
3563 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3564 if (status < 0)
3565 goto error;
3566
3567 /* reset datapath for OFDM, processors first */
3568 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3569 if (status < 0)
3570 goto error;
3571 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3572 if (status < 0)
3573 goto error;
3574 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3575 if (status < 0)
3576 goto error;
3577
3578 /* IQM setup */
3579 /* synchronize on ofdstate->m_festart */
3580 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3581 if (status < 0)
3582 goto error;
3583 /* window size for clipping ADC detection */
3584 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3585 if (status < 0)
3586 goto error;
3587 /* window size for for sense pre-SAW detection */
3588 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3589 if (status < 0)
3590 goto error;
3591 /* sense threshold for sense pre-SAW detection */
3592 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3593 if (status < 0)
3594 goto error;
3595 status = SetIqmAf(state, true);
3596 if (status < 0)
3597 goto error;
3598
3599 status = write16(state, IQM_AF_AGC_RF__A, 0);
3600 if (status < 0)
3601 goto error;
3602
3603 /* Impulse noise cruncher setup */
3604 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3605 if (status < 0)
3606 goto error;
3607 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3608 if (status < 0)
3609 goto error;
3610 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3611 if (status < 0)
3612 goto error;
3613
3614 status = write16(state, IQM_RC_STRETCH__A, 16);
3615 if (status < 0)
3616 goto error;
3617 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3618 if (status < 0)
3619 goto error;
3620 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3621 if (status < 0)
3622 goto error;
3623 status = write16(state, IQM_CF_SCALE__A, 1600);
3624 if (status < 0)
3625 goto error;
3626 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3627 if (status < 0)
3628 goto error;
3629
3630 /* virtual clipping threshold for clipping ADC detection */
3631 status = write16(state, IQM_AF_CLP_TH__A, 448);
3632 if (status < 0)
3633 goto error;
3634 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3635 if (status < 0)
3636 goto error;
3637
3638 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3639 if (status < 0)
3640 goto error;
3641
3642 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3643 if (status < 0)
3644 goto error;
3645 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3646 if (status < 0)
3647 goto error;
3648 /* enable power measurement interrupt */
3649 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3650 if (status < 0)
3651 goto error;
3652 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3653 if (status < 0)
3654 goto error;
3655
3656 /* IQM will not be reset from here, sync ADC and update/init AGC */
3657 status = ADCSynchronization(state);
3658 if (status < 0)
3659 goto error;
3660 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3661 if (status < 0)
3662 goto error;
3663
3664 /* Halt SCU to enable safe non-atomic accesses */
3665 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3666 if (status < 0)
3667 goto error;
3668
3669 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3670 if (status < 0)
3671 goto error;
3672 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3673 if (status < 0)
3674 goto error;
3675
3676 /* Set Noise Estimation notch width and enable DC fix */
3677 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3678 if (status < 0)
3679 goto error;
3680 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3681 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3682 if (status < 0)
3683 goto error;
3684
3685 /* Activate SCU to enable SCU commands */
3686 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3687 if (status < 0)
3688 goto error;
3689
3690 if (!state->m_DRXK_A3_ROM_CODE) {
3691 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3692 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3693 if (status < 0)
3694 goto error;
3695 }
3696
3697 /* OFDM_SC setup */
3698#ifdef COMPILE_FOR_NONRT
3699 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3700 if (status < 0)
3701 goto error;
3702 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3703 if (status < 0)
3704 goto error;
3705#endif
3706
3707 /* FEC setup */
3708 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3709 if (status < 0)
3710 goto error;
3711
3712
3713#ifdef COMPILE_FOR_NONRT
3714 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3715 if (status < 0)
3716 goto error;
3717#else
3718 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3719 if (status < 0)
3720 goto error;
3721#endif
3722 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3723 if (status < 0)
3724 goto error;
3725
3726 /* Setup MPEG bus */
3727 status = MPEGTSDtoSetup(state, OM_DVBT);
3728 if (status < 0)
3729 goto error;
3730 /* Set DVBT Presets */
3731 status = DVBTActivatePresets(state);
3732 if (status < 0)
3733 goto error;
3734
3735error:
3736 if (status < 0)
3737 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003738 return status;
3739}
3740
3741/*============================================================================*/
3742/**
3743* \brief Start dvbt demodulating for channel.
3744* \param demod instance of demodulator.
3745* \return DRXStatus_t.
3746*/
3747static int DVBTStart(struct drxk_state *state)
3748{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003749 u16 param1;
3750 int status;
3751 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003752
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003753 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003754 /* Start correct processes to get in lock */
3755 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003756 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3757 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3758 if (status < 0)
3759 goto error;
3760 /* Start FEC OC */
3761 status = MPEGTSStart(state);
3762 if (status < 0)
3763 goto error;
3764 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3765 if (status < 0)
3766 goto error;
3767error:
3768 if (status < 0)
3769 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003770 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003771}
3772
3773
3774/*============================================================================*/
3775
3776/**
3777* \brief Set up dvbt demodulator for channel.
3778* \param demod instance of demodulator.
3779* \return DRXStatus_t.
3780* // original DVBTSetChannel()
3781*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003782static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3783 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003784{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003785 u16 cmdResult = 0;
3786 u16 transmissionParams = 0;
3787 u16 operationMode = 0;
3788 u32 iqmRcRateOfs = 0;
3789 u32 bandwidth = 0;
3790 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003791 int status;
3792
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003793 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003794
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003795 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3796 if (status < 0)
3797 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003798
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003799 /* Halt SCU to enable safe non-atomic accesses */
3800 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3801 if (status < 0)
3802 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003803
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003804 /* Stop processors */
3805 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3806 if (status < 0)
3807 goto error;
3808 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3809 if (status < 0)
3810 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003811
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003812 /* Mandatory fix, always stop CP, required to set spl offset back to
3813 hardware default (is set to 0 by ucode during pilot detection */
3814 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3815 if (status < 0)
3816 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003817
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003818 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003819
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003820 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003821 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003822 case TRANSMISSION_MODE_AUTO:
3823 default:
3824 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3825 /* fall through , try first guess DRX_FFTMODE_8K */
3826 case TRANSMISSION_MODE_8K:
3827 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003828 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003829 case TRANSMISSION_MODE_2K:
3830 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003831 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003832 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003833
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003834 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003835 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003836 default:
3837 case GUARD_INTERVAL_AUTO:
3838 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3839 /* fall through , try first guess DRX_GUARD_1DIV4 */
3840 case GUARD_INTERVAL_1_4:
3841 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003842 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003843 case GUARD_INTERVAL_1_32:
3844 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003845 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003846 case GUARD_INTERVAL_1_16:
3847 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003848 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003849 case GUARD_INTERVAL_1_8:
3850 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003851 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003852 }
3853
3854 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003855 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003856 case HIERARCHY_AUTO:
3857 case HIERARCHY_NONE:
3858 default:
3859 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3860 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3861 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3862 /* break; */
3863 case HIERARCHY_1:
3864 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3865 break;
3866 case HIERARCHY_2:
3867 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3868 break;
3869 case HIERARCHY_4:
3870 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3871 break;
3872 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003873
3874
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003875 /* modulation */
3876 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003877 case QAM_AUTO:
3878 default:
3879 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3880 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3881 case QAM_64:
3882 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3883 break;
3884 case QPSK:
3885 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3886 break;
3887 case QAM_16:
3888 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3889 break;
3890 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003891#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003892 /* No hierachical channels support in BDA */
3893 /* Priority (only for hierarchical channels) */
3894 switch (channel->priority) {
3895 case DRX_PRIORITY_LOW:
3896 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3897 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3898 OFDM_EC_SB_PRIOR_LO);
3899 break;
3900 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003901 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003902 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3903 OFDM_EC_SB_PRIOR_HI));
3904 break;
3905 case DRX_PRIORITY_UNKNOWN: /* fall through */
3906 default:
3907 status = -EINVAL;
3908 goto error;
3909 }
3910#else
3911 /* Set Priorty high */
3912 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3913 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3914 if (status < 0)
3915 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003916#endif
3917
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003918 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003919 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003920 case FEC_AUTO:
3921 default:
3922 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3923 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3924 case FEC_2_3:
3925 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3926 break;
3927 case FEC_1_2:
3928 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3929 break;
3930 case FEC_3_4:
3931 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3932 break;
3933 case FEC_5_6:
3934 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3935 break;
3936 case FEC_7_8:
3937 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3938 break;
3939 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003940
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003941 /* SAW filter selection: normaly not necesarry, but if wanted
3942 the application can select a SAW filter via the driver by using UIOs */
3943 /* First determine real bandwidth (Hz) */
3944 /* Also set delay for impulse noise cruncher */
3945 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3946 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3947 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003948 switch (state->props.bandwidth_hz) {
3949 case 0:
3950 state->props.bandwidth_hz = 8000000;
3951 /* fall though */
3952 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003953 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3954 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003955 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003956 goto error;
3957 /* cochannel protection for PAL 8 MHz */
3958 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3959 if (status < 0)
3960 goto error;
3961 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3962 if (status < 0)
3963 goto error;
3964 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3965 if (status < 0)
3966 goto error;
3967 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3968 if (status < 0)
3969 goto error;
3970 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003971 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003972 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3973 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3974 if (status < 0)
3975 goto error;
3976 /* cochannel protection for PAL 7 MHz */
3977 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3978 if (status < 0)
3979 goto error;
3980 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3981 if (status < 0)
3982 goto error;
3983 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3984 if (status < 0)
3985 goto error;
3986 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3987 if (status < 0)
3988 goto error;
3989 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003990 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003991 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3992 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3993 if (status < 0)
3994 goto error;
3995 /* cochannel protection for NTSC 6 MHz */
3996 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3997 if (status < 0)
3998 goto error;
3999 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
4000 if (status < 0)
4001 goto error;
4002 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
4003 if (status < 0)
4004 goto error;
4005 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
4006 if (status < 0)
4007 goto error;
4008 break;
4009 default:
4010 status = -EINVAL;
4011 goto error;
4012 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004013
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004014 if (iqmRcRateOfs == 0) {
4015 /* Now compute IQM_RC_RATE_OFS
4016 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4017 =>
4018 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4019 */
4020 /* (SysFreq / BandWidth) * (2^28) */
4021 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4022 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4023 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4024 iqmRcRateOfs = Frac28a((u32)
4025 ((state->m_sysClockFreq *
4026 1000) / 3), bandwidth);
4027 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4028 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4029 iqmRcRateOfs += 0x80L;
4030 iqmRcRateOfs = iqmRcRateOfs >> 7;
4031 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4032 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4033 }
4034
4035 iqmRcRateOfs &=
4036 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4037 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4038 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4039 if (status < 0)
4040 goto error;
4041
4042 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004043
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004044#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004045 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4046 if (status < 0)
4047 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004048#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004049 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4050 if (status < 0)
4051 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004052
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004053 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004054
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004055 /* Activate SCU to enable SCU commands */
4056 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4057 if (status < 0)
4058 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004059
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004060 /* Enable SC after setting all other parameters */
4061 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4062 if (status < 0)
4063 goto error;
4064 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4065 if (status < 0)
4066 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004067
4068
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004069 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4070 if (status < 0)
4071 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004072
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004073 /* Write SC parameter registers, set all AUTO flags in operation mode */
4074 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4075 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4076 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4077 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4078 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4079 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4080 0, transmissionParams, param1, 0, 0, 0);
4081 if (status < 0)
4082 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004083
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004084 if (!state->m_DRXK_A3_ROM_CODE)
4085 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4086error:
4087 if (status < 0)
4088 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004089
4090 return status;
4091}
4092
4093
4094/*============================================================================*/
4095
4096/**
4097* \brief Retreive lock status .
4098* \param demod Pointer to demodulator instance.
4099* \param lockStat Pointer to lock status structure.
4100* \return DRXStatus_t.
4101*
4102*/
4103static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4104{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004105 int status;
4106 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4107 OFDM_SC_RA_RAM_LOCK_FEC__M);
4108 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4109 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004110
Oliver Endrissebc7de22011-07-03 13:49:44 -03004111 u16 ScRaRamLock = 0;
4112 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004113
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004114 dprintk(1, "\n");
4115
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004116 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004117 /* driver 0.9.0 */
4118 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004119 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004120 if (status < 0)
4121 goto end;
4122 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4123 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004124
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004125 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004126 if (status < 0)
4127 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004128
Oliver Endrissebc7de22011-07-03 13:49:44 -03004129 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4130 *pLockStatus = MPEG_LOCK;
4131 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4132 *pLockStatus = FEC_LOCK;
4133 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4134 *pLockStatus = DEMOD_LOCK;
4135 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4136 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004137end:
4138 if (status < 0)
4139 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004140
Oliver Endrissebc7de22011-07-03 13:49:44 -03004141 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004142}
4143
Oliver Endrissebc7de22011-07-03 13:49:44 -03004144static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004145{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004146 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004147 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004148
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004149 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004150 status = CtrlPowerMode(state, &powerMode);
4151 if (status < 0)
4152 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004153
Oliver Endrissebc7de22011-07-03 13:49:44 -03004154 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004155}
4156
4157
Oliver Endrissebc7de22011-07-03 13:49:44 -03004158/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004159static int PowerDownQAM(struct drxk_state *state)
4160{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004161 u16 data = 0;
4162 u16 cmdResult;
4163 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004164
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004165 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004166 status = read16(state, SCU_COMM_EXEC__A, &data);
4167 if (status < 0)
4168 goto error;
4169 if (data == SCU_COMM_EXEC_ACTIVE) {
4170 /*
4171 STOP demodulator
4172 QAM and HW blocks
4173 */
4174 /* stop all comstate->m_exec */
4175 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004176 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004177 goto error;
4178 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 -03004179 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004180 goto error;
4181 }
4182 /* powerdown AFE */
4183 status = SetIqmAf(state, false);
4184
4185error:
4186 if (status < 0)
4187 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004188
Oliver Endrissebc7de22011-07-03 13:49:44 -03004189 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004190}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004191
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004192/*============================================================================*/
4193
4194/**
4195* \brief Setup of the QAM Measurement intervals for signal quality
4196* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004197* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004198* \return DRXStatus_t.
4199*
4200* NOTE:
4201* Take into account that for certain settings the errorcounters can overflow.
4202* The implementation does not check this.
4203*
4204*/
4205static int SetQAMMeasurement(struct drxk_state *state,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004206 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004207 u32 symbolRate)
4208{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004209 u32 fecBitsDesired = 0; /* BER accounting period */
4210 u32 fecRsPeriodTotal = 0; /* Total period */
4211 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4212 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004213 int status = 0;
4214
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004215 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004216
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004217 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004218 /* fecBitsDesired = symbolRate [kHz] *
4219 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004220 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004221 SyncLoss (== 1) *
4222 ViterbiLoss (==1)
4223 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004224 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004225 case DRX_CONSTELLATION_QAM16:
4226 fecBitsDesired = 4 * symbolRate;
4227 break;
4228 case DRX_CONSTELLATION_QAM32:
4229 fecBitsDesired = 5 * symbolRate;
4230 break;
4231 case DRX_CONSTELLATION_QAM64:
4232 fecBitsDesired = 6 * symbolRate;
4233 break;
4234 case DRX_CONSTELLATION_QAM128:
4235 fecBitsDesired = 7 * symbolRate;
4236 break;
4237 case DRX_CONSTELLATION_QAM256:
4238 fecBitsDesired = 8 * symbolRate;
4239 break;
4240 default:
4241 status = -EINVAL;
4242 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004243 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004244 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004245
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004246 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4247 fecBitsDesired *= 500; /* meas. period [ms] */
4248
4249 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4250 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4251 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4252
4253 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4254 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4255 if (fecRsPrescale == 0) {
4256 /* Divide by zero (though impossible) */
4257 status = -EINVAL;
4258 if (status < 0)
4259 goto error;
4260 }
4261 fecRsPeriod =
4262 ((u16) fecRsPeriodTotal +
4263 (fecRsPrescale >> 1)) / fecRsPrescale;
4264
4265 /* write corresponding registers */
4266 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4267 if (status < 0)
4268 goto error;
4269 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4270 if (status < 0)
4271 goto error;
4272 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4273error:
4274 if (status < 0)
4275 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004276 return status;
4277}
4278
Oliver Endrissebc7de22011-07-03 13:49:44 -03004279static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004280{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004281 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004282
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004283 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004284 /* QAM Equalizer Setup */
4285 /* Equalizer */
4286 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4287 if (status < 0)
4288 goto error;
4289 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4290 if (status < 0)
4291 goto error;
4292 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4293 if (status < 0)
4294 goto error;
4295 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4296 if (status < 0)
4297 goto error;
4298 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4299 if (status < 0)
4300 goto error;
4301 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4302 if (status < 0)
4303 goto error;
4304 /* Decision Feedback Equalizer */
4305 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4306 if (status < 0)
4307 goto error;
4308 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4309 if (status < 0)
4310 goto error;
4311 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4312 if (status < 0)
4313 goto error;
4314 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4315 if (status < 0)
4316 goto error;
4317 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4318 if (status < 0)
4319 goto error;
4320 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4321 if (status < 0)
4322 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004323
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004324 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4325 if (status < 0)
4326 goto error;
4327 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4328 if (status < 0)
4329 goto error;
4330 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4331 if (status < 0)
4332 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004333
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004334 /* QAM Slicer Settings */
4335 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4336 if (status < 0)
4337 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004338
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004339 /* QAM Loop Controller Coeficients */
4340 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4341 if (status < 0)
4342 goto error;
4343 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4344 if (status < 0)
4345 goto error;
4346 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4347 if (status < 0)
4348 goto error;
4349 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4350 if (status < 0)
4351 goto error;
4352 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4353 if (status < 0)
4354 goto error;
4355 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4356 if (status < 0)
4357 goto error;
4358 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4359 if (status < 0)
4360 goto error;
4361 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4362 if (status < 0)
4363 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004364
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004365 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4366 if (status < 0)
4367 goto error;
4368 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4369 if (status < 0)
4370 goto error;
4371 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4372 if (status < 0)
4373 goto error;
4374 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4375 if (status < 0)
4376 goto error;
4377 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4378 if (status < 0)
4379 goto error;
4380 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4381 if (status < 0)
4382 goto error;
4383 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4384 if (status < 0)
4385 goto error;
4386 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4387 if (status < 0)
4388 goto error;
4389 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4390 if (status < 0)
4391 goto error;
4392 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4393 if (status < 0)
4394 goto error;
4395 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4396 if (status < 0)
4397 goto error;
4398 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4399 if (status < 0)
4400 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004401
4402
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004403 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004404
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004405 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4406 if (status < 0)
4407 goto error;
4408 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4409 if (status < 0)
4410 goto error;
4411 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4412 if (status < 0)
4413 goto error;
4414 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4415 if (status < 0)
4416 goto error;
4417 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4418 if (status < 0)
4419 goto error;
4420 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4421 if (status < 0)
4422 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004423
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004424 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4425 if (status < 0)
4426 goto error;
4427 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4428 if (status < 0)
4429 goto error;
4430 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4431 if (status < 0)
4432 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004433
4434
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004435 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004436
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004437 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4438 if (status < 0)
4439 goto error;
4440 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4441 if (status < 0)
4442 goto error;
4443 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4444 if (status < 0)
4445 goto error;
4446 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4447 if (status < 0)
4448 goto error;
4449 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4450 if (status < 0)
4451 goto error;
4452 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4453 if (status < 0)
4454 goto error;
4455 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4456 if (status < 0)
4457 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004458
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004459error:
4460 if (status < 0)
4461 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004462 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004463}
4464
4465/*============================================================================*/
4466
4467/**
4468* \brief QAM32 specific setup
4469* \param demod instance of demod.
4470* \return DRXStatus_t.
4471*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004472static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004473{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004474 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004475
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004476 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004477
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004478 /* QAM Equalizer Setup */
4479 /* Equalizer */
4480 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4481 if (status < 0)
4482 goto error;
4483 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4484 if (status < 0)
4485 goto error;
4486 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4487 if (status < 0)
4488 goto error;
4489 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4490 if (status < 0)
4491 goto error;
4492 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4493 if (status < 0)
4494 goto error;
4495 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4496 if (status < 0)
4497 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004498
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004499 /* Decision Feedback Equalizer */
4500 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4501 if (status < 0)
4502 goto error;
4503 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4504 if (status < 0)
4505 goto error;
4506 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4507 if (status < 0)
4508 goto error;
4509 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4510 if (status < 0)
4511 goto error;
4512 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4513 if (status < 0)
4514 goto error;
4515 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4516 if (status < 0)
4517 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004518
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004519 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4520 if (status < 0)
4521 goto error;
4522 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4523 if (status < 0)
4524 goto error;
4525 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4526 if (status < 0)
4527 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004528
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004529 /* QAM Slicer Settings */
4530
4531 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4532 if (status < 0)
4533 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004534
4535
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004536 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004537
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004538 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4539 if (status < 0)
4540 goto error;
4541 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4542 if (status < 0)
4543 goto error;
4544 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4545 if (status < 0)
4546 goto error;
4547 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4548 if (status < 0)
4549 goto error;
4550 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4551 if (status < 0)
4552 goto error;
4553 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4554 if (status < 0)
4555 goto error;
4556 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4557 if (status < 0)
4558 goto error;
4559 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4560 if (status < 0)
4561 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004562
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004563 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4564 if (status < 0)
4565 goto error;
4566 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4567 if (status < 0)
4568 goto error;
4569 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4570 if (status < 0)
4571 goto error;
4572 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4573 if (status < 0)
4574 goto error;
4575 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4576 if (status < 0)
4577 goto error;
4578 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4579 if (status < 0)
4580 goto error;
4581 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4582 if (status < 0)
4583 goto error;
4584 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4585 if (status < 0)
4586 goto error;
4587 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4588 if (status < 0)
4589 goto error;
4590 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4591 if (status < 0)
4592 goto error;
4593 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4594 if (status < 0)
4595 goto error;
4596 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4597 if (status < 0)
4598 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004599
4600
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004601 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004602
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004603 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4604 if (status < 0)
4605 goto error;
4606 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4607 if (status < 0)
4608 goto error;
4609 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4610 if (status < 0)
4611 goto error;
4612 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4613 if (status < 0)
4614 goto error;
4615 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4616 if (status < 0)
4617 goto error;
4618 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4619 if (status < 0)
4620 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004621
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004622 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4623 if (status < 0)
4624 goto error;
4625 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4626 if (status < 0)
4627 goto error;
4628 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4629 if (status < 0)
4630 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004631
4632
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004633 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004634
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004635 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4636 if (status < 0)
4637 goto error;
4638 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4639 if (status < 0)
4640 goto error;
4641 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4642 if (status < 0)
4643 goto error;
4644 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4645 if (status < 0)
4646 goto error;
4647 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4648 if (status < 0)
4649 goto error;
4650 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4651 if (status < 0)
4652 goto error;
4653 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4654error:
4655 if (status < 0)
4656 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004657 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004658}
4659
4660/*============================================================================*/
4661
4662/**
4663* \brief QAM64 specific setup
4664* \param demod instance of demod.
4665* \return DRXStatus_t.
4666*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004667static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004668{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004669 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004670
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004671 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004672 /* QAM Equalizer Setup */
4673 /* Equalizer */
4674 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4675 if (status < 0)
4676 goto error;
4677 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4678 if (status < 0)
4679 goto error;
4680 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4681 if (status < 0)
4682 goto error;
4683 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4684 if (status < 0)
4685 goto error;
4686 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4687 if (status < 0)
4688 goto error;
4689 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4690 if (status < 0)
4691 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004692
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004693 /* Decision Feedback Equalizer */
4694 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4695 if (status < 0)
4696 goto error;
4697 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4698 if (status < 0)
4699 goto error;
4700 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4701 if (status < 0)
4702 goto error;
4703 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4704 if (status < 0)
4705 goto error;
4706 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4707 if (status < 0)
4708 goto error;
4709 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4710 if (status < 0)
4711 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004712
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004713 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4714 if (status < 0)
4715 goto error;
4716 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4717 if (status < 0)
4718 goto error;
4719 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4720 if (status < 0)
4721 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004722
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004723 /* QAM Slicer Settings */
4724 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4725 if (status < 0)
4726 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004727
4728
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004729 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004730
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004731 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4732 if (status < 0)
4733 goto error;
4734 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4735 if (status < 0)
4736 goto error;
4737 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4738 if (status < 0)
4739 goto error;
4740 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4741 if (status < 0)
4742 goto error;
4743 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4744 if (status < 0)
4745 goto error;
4746 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4747 if (status < 0)
4748 goto error;
4749 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4750 if (status < 0)
4751 goto error;
4752 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4753 if (status < 0)
4754 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004755
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004756 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4757 if (status < 0)
4758 goto error;
4759 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4760 if (status < 0)
4761 goto error;
4762 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4763 if (status < 0)
4764 goto error;
4765 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4766 if (status < 0)
4767 goto error;
4768 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4769 if (status < 0)
4770 goto error;
4771 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4772 if (status < 0)
4773 goto error;
4774 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4775 if (status < 0)
4776 goto error;
4777 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4778 if (status < 0)
4779 goto error;
4780 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4781 if (status < 0)
4782 goto error;
4783 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4784 if (status < 0)
4785 goto error;
4786 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4787 if (status < 0)
4788 goto error;
4789 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4790 if (status < 0)
4791 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004792
4793
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004794 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004795
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004796 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4797 if (status < 0)
4798 goto error;
4799 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4800 if (status < 0)
4801 goto error;
4802 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4803 if (status < 0)
4804 goto error;
4805 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4806 if (status < 0)
4807 goto error;
4808 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4809 if (status < 0)
4810 goto error;
4811 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4812 if (status < 0)
4813 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004814
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004815 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4816 if (status < 0)
4817 goto error;
4818 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4819 if (status < 0)
4820 goto error;
4821 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4822 if (status < 0)
4823 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004824
4825
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004826 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004827
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004828 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4829 if (status < 0)
4830 goto error;
4831 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4832 if (status < 0)
4833 goto error;
4834 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4835 if (status < 0)
4836 goto error;
4837 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4838 if (status < 0)
4839 goto error;
4840 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4841 if (status < 0)
4842 goto error;
4843 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4844 if (status < 0)
4845 goto error;
4846 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4847error:
4848 if (status < 0)
4849 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004850
Oliver Endrissebc7de22011-07-03 13:49:44 -03004851 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004852}
4853
4854/*============================================================================*/
4855
4856/**
4857* \brief QAM128 specific setup
4858* \param demod: instance of demod.
4859* \return DRXStatus_t.
4860*/
4861static int SetQAM128(struct drxk_state *state)
4862{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004863 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004864
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004865 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004866 /* QAM Equalizer Setup */
4867 /* Equalizer */
4868 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4869 if (status < 0)
4870 goto error;
4871 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4872 if (status < 0)
4873 goto error;
4874 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4875 if (status < 0)
4876 goto error;
4877 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4878 if (status < 0)
4879 goto error;
4880 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4881 if (status < 0)
4882 goto error;
4883 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4884 if (status < 0)
4885 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004886
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004887 /* Decision Feedback Equalizer */
4888 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4889 if (status < 0)
4890 goto error;
4891 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4892 if (status < 0)
4893 goto error;
4894 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4895 if (status < 0)
4896 goto error;
4897 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4898 if (status < 0)
4899 goto error;
4900 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4901 if (status < 0)
4902 goto error;
4903 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4904 if (status < 0)
4905 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004906
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004907 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4908 if (status < 0)
4909 goto error;
4910 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4911 if (status < 0)
4912 goto error;
4913 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4914 if (status < 0)
4915 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004916
4917
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004918 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004919
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004920 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4921 if (status < 0)
4922 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004923
4924
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004925 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004926
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004927 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4928 if (status < 0)
4929 goto error;
4930 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4931 if (status < 0)
4932 goto error;
4933 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4934 if (status < 0)
4935 goto error;
4936 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4937 if (status < 0)
4938 goto error;
4939 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4940 if (status < 0)
4941 goto error;
4942 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4943 if (status < 0)
4944 goto error;
4945 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4946 if (status < 0)
4947 goto error;
4948 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4949 if (status < 0)
4950 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004951
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004952 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4953 if (status < 0)
4954 goto error;
4955 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4956 if (status < 0)
4957 goto error;
4958 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4959 if (status < 0)
4960 goto error;
4961 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4962 if (status < 0)
4963 goto error;
4964 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4965 if (status < 0)
4966 goto error;
4967 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4968 if (status < 0)
4969 goto error;
4970 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4971 if (status < 0)
4972 goto error;
4973 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4974 if (status < 0)
4975 goto error;
4976 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4977 if (status < 0)
4978 goto error;
4979 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4980 if (status < 0)
4981 goto error;
4982 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4983 if (status < 0)
4984 goto error;
4985 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4986 if (status < 0)
4987 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004988
4989
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004990 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004991
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004992 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4993 if (status < 0)
4994 goto error;
4995 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4996 if (status < 0)
4997 goto error;
4998 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4999 if (status < 0)
5000 goto error;
5001 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5002 if (status < 0)
5003 goto error;
5004 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
5005 if (status < 0)
5006 goto error;
5007 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5008 if (status < 0)
5009 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005010
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005011 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5012 if (status < 0)
5013 goto error;
5014 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5015 if (status < 0)
5016 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005017
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005018 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5019 if (status < 0)
5020 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005021
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005022 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005023
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005024 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5025 if (status < 0)
5026 goto error;
5027 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5028 if (status < 0)
5029 goto error;
5030 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5031 if (status < 0)
5032 goto error;
5033 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5034 if (status < 0)
5035 goto error;
5036 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5037 if (status < 0)
5038 goto error;
5039 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5040 if (status < 0)
5041 goto error;
5042 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5043error:
5044 if (status < 0)
5045 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005046
Oliver Endrissebc7de22011-07-03 13:49:44 -03005047 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005048}
5049
5050/*============================================================================*/
5051
5052/**
5053* \brief QAM256 specific setup
5054* \param demod: instance of demod.
5055* \return DRXStatus_t.
5056*/
5057static int SetQAM256(struct drxk_state *state)
5058{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005059 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005060
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005061 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005062 /* QAM Equalizer Setup */
5063 /* Equalizer */
5064 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5065 if (status < 0)
5066 goto error;
5067 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5068 if (status < 0)
5069 goto error;
5070 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5071 if (status < 0)
5072 goto error;
5073 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5074 if (status < 0)
5075 goto error;
5076 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5077 if (status < 0)
5078 goto error;
5079 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5080 if (status < 0)
5081 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005082
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005083 /* Decision Feedback Equalizer */
5084 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5085 if (status < 0)
5086 goto error;
5087 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5088 if (status < 0)
5089 goto error;
5090 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5091 if (status < 0)
5092 goto error;
5093 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5094 if (status < 0)
5095 goto error;
5096 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5097 if (status < 0)
5098 goto error;
5099 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5100 if (status < 0)
5101 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005102
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005103 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5104 if (status < 0)
5105 goto error;
5106 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5107 if (status < 0)
5108 goto error;
5109 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5110 if (status < 0)
5111 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005112
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005113 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005114
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005115 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5116 if (status < 0)
5117 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005118
5119
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005120 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005121
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005122 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5123 if (status < 0)
5124 goto error;
5125 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5126 if (status < 0)
5127 goto error;
5128 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5129 if (status < 0)
5130 goto error;
5131 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5132 if (status < 0)
5133 goto error;
5134 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5135 if (status < 0)
5136 goto error;
5137 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5138 if (status < 0)
5139 goto error;
5140 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5141 if (status < 0)
5142 goto error;
5143 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5144 if (status < 0)
5145 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005146
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005147 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5148 if (status < 0)
5149 goto error;
5150 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5151 if (status < 0)
5152 goto error;
5153 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5154 if (status < 0)
5155 goto error;
5156 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5157 if (status < 0)
5158 goto error;
5159 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5160 if (status < 0)
5161 goto error;
5162 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5163 if (status < 0)
5164 goto error;
5165 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5166 if (status < 0)
5167 goto error;
5168 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5169 if (status < 0)
5170 goto error;
5171 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5172 if (status < 0)
5173 goto error;
5174 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5175 if (status < 0)
5176 goto error;
5177 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5178 if (status < 0)
5179 goto error;
5180 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5181 if (status < 0)
5182 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005183
5184
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005185 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005186
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005187 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5188 if (status < 0)
5189 goto error;
5190 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5191 if (status < 0)
5192 goto error;
5193 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5194 if (status < 0)
5195 goto error;
5196 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5197 if (status < 0)
5198 goto error;
5199 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5200 if (status < 0)
5201 goto error;
5202 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5203 if (status < 0)
5204 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005205
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005206 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5207 if (status < 0)
5208 goto error;
5209 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5210 if (status < 0)
5211 goto error;
5212 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5213 if (status < 0)
5214 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005215
5216
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005217 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005218
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005219 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5220 if (status < 0)
5221 goto error;
5222 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5223 if (status < 0)
5224 goto error;
5225 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5226 if (status < 0)
5227 goto error;
5228 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5229 if (status < 0)
5230 goto error;
5231 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5232 if (status < 0)
5233 goto error;
5234 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5235 if (status < 0)
5236 goto error;
5237 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5238error:
5239 if (status < 0)
5240 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005241 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005242}
5243
5244
5245/*============================================================================*/
5246/**
5247* \brief Reset QAM block.
5248* \param demod: instance of demod.
5249* \param channel: pointer to channel data.
5250* \return DRXStatus_t.
5251*/
5252static int QAMResetQAM(struct drxk_state *state)
5253{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005254 int status;
5255 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005256
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005257 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005258 /* Stop QAM comstate->m_exec */
5259 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5260 if (status < 0)
5261 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005262
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005263 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5264error:
5265 if (status < 0)
5266 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005267 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005268}
5269
5270/*============================================================================*/
5271
5272/**
5273* \brief Set QAM symbolrate.
5274* \param demod: instance of demod.
5275* \param channel: pointer to channel data.
5276* \return DRXStatus_t.
5277*/
5278static int QAMSetSymbolrate(struct drxk_state *state)
5279{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005280 u32 adcFrequency = 0;
5281 u32 symbFreq = 0;
5282 u32 iqmRcRate = 0;
5283 u16 ratesel = 0;
5284 u32 lcSymbRate = 0;
5285 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005286
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005287 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005288 /* Select & calculate correct IQM rate */
5289 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5290 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005291 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5292 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005293 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005294 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005295 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005296 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005297 ratesel = 1;
5298 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5299 if (status < 0)
5300 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005301
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005302 /*
5303 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5304 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005305 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005306 if (symbFreq == 0) {
5307 /* Divide by zero */
5308 status = -EINVAL;
5309 goto error;
5310 }
5311 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5312 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5313 (1 << 23);
5314 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5315 if (status < 0)
5316 goto error;
5317 state->m_iqmRcRate = iqmRcRate;
5318 /*
5319 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5320 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005321 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005322 if (adcFrequency == 0) {
5323 /* Divide by zero */
5324 status = -EINVAL;
5325 goto error;
5326 }
5327 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5328 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5329 16);
5330 if (lcSymbRate > 511)
5331 lcSymbRate = 511;
5332 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005333
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005334error:
5335 if (status < 0)
5336 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005337 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005338}
5339
5340/*============================================================================*/
5341
5342/**
5343* \brief Get QAM lock status.
5344* \param demod: instance of demod.
5345* \param channel: pointer to channel data.
5346* \return DRXStatus_t.
5347*/
5348
5349static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5350{
5351 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005352 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005353
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005354 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005355 *pLockStatus = NOT_LOCKED;
5356 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005357 SCU_RAM_COMMAND_STANDARD_QAM |
5358 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5359 Result);
5360 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005361 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005362
5363 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005364 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005365 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005366 /* 0x4000 DEMOD LOCKED */
5367 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005368 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005369 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5370 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005371 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005372 /* 0xC000 NEVER LOCKED */
5373 /* (system will never be able to lock to the signal) */
5374 /* TODO: check this, intermediate & standard specific lock states are not
5375 taken into account here */
5376 *pLockStatus = NEVER_LOCK;
5377 }
5378 return status;
5379}
5380
5381#define QAM_MIRROR__M 0x03
5382#define QAM_MIRROR_NORMAL 0x00
5383#define QAM_MIRRORED 0x01
5384#define QAM_MIRROR_AUTO_ON 0x02
5385#define QAM_LOCKRANGE__M 0x10
5386#define QAM_LOCKRANGE_NORMAL 0x10
5387
Oliver Endrissebc7de22011-07-03 13:49:44 -03005388static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5389 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005390{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005391 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005392 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5393 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005394
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005395 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005396 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005397 * STEP 1: reset demodulator
5398 * resets FEC DI and FEC RS
5399 * resets QAM block
5400 * resets SCU variables
5401 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005402 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005403 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005404 goto error;
5405 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5406 if (status < 0)
5407 goto error;
5408 status = QAMResetQAM(state);
5409 if (status < 0)
5410 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005411
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005412 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005413 * STEP 2: configure demodulator
5414 * -set params; resets IQM,QAM,FEC HW; initializes some
5415 * SCU variables
5416 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005417 status = QAMSetSymbolrate(state);
5418 if (status < 0)
5419 goto error;
5420
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005421 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005422 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005423 case QAM_256:
5424 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5425 break;
5426 case QAM_AUTO:
5427 case QAM_64:
5428 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5429 break;
5430 case QAM_16:
5431 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5432 break;
5433 case QAM_32:
5434 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5435 break;
5436 case QAM_128:
5437 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5438 break;
5439 default:
5440 status = -EINVAL;
5441 break;
5442 }
5443 if (status < 0)
5444 goto error;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005445 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005446 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005447 if (state->m_OperationMode == OM_QAM_ITU_C)
5448 setParamParameters[2] = QAM_TOP_ANNEX_C;
5449 else
5450 setParamParameters[2] = QAM_TOP_ANNEX_A;
5451 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5452 /* Env parameters */
5453 /* check for LOCKRANGE Extented */
5454 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005455
5456 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 -03005457 if (status < 0) {
5458 /* Fall-back to the simpler call */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005459 if (state->m_OperationMode == OM_QAM_ITU_C)
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005460 setParamParameters[0] = QAM_TOP_ANNEX_C;
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005461 else
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005462 setParamParameters[0] = QAM_TOP_ANNEX_A;
5463 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult);
5464 if (status < 0)
5465 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005466
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005467 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005468 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005469 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
5470 }
5471 if (status < 0)
5472 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005473
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005474 /*
5475 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005476 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005477 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005478#if 0
5479 status = SetFrequency(channel, tunerFreqOffset));
5480 if (status < 0)
5481 goto error;
5482#endif
5483 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5484 if (status < 0)
5485 goto error;
5486
5487 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005488 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005489 if (status < 0)
5490 goto error;
5491
5492 /* Reset default values */
5493 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5494 if (status < 0)
5495 goto error;
5496 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5497 if (status < 0)
5498 goto error;
5499
5500 /* Reset default LC values */
5501 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5502 if (status < 0)
5503 goto error;
5504 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5505 if (status < 0)
5506 goto error;
5507 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5508 if (status < 0)
5509 goto error;
5510 status = write16(state, QAM_LC_MODE__A, 7);
5511 if (status < 0)
5512 goto error;
5513
5514 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5515 if (status < 0)
5516 goto error;
5517 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5518 if (status < 0)
5519 goto error;
5520 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5521 if (status < 0)
5522 goto error;
5523 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5524 if (status < 0)
5525 goto error;
5526 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5527 if (status < 0)
5528 goto error;
5529 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5530 if (status < 0)
5531 goto error;
5532 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5533 if (status < 0)
5534 goto error;
5535 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5536 if (status < 0)
5537 goto error;
5538 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5539 if (status < 0)
5540 goto error;
5541 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5542 if (status < 0)
5543 goto error;
5544 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5545 if (status < 0)
5546 goto error;
5547 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5548 if (status < 0)
5549 goto error;
5550 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5551 if (status < 0)
5552 goto error;
5553 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5554 if (status < 0)
5555 goto error;
5556 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5557 if (status < 0)
5558 goto error;
5559
5560 /* Mirroring, QAM-block starting point not inverted */
5561 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5562 if (status < 0)
5563 goto error;
5564
5565 /* Halt SCU to enable safe non-atomic accesses */
5566 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5567 if (status < 0)
5568 goto error;
5569
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005570 /* STEP 4: modulation specific setup */
5571 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005572 case QAM_16:
5573 status = SetQAM16(state);
5574 break;
5575 case QAM_32:
5576 status = SetQAM32(state);
5577 break;
5578 case QAM_AUTO:
5579 case QAM_64:
5580 status = SetQAM64(state);
5581 break;
5582 case QAM_128:
5583 status = SetQAM128(state);
5584 break;
5585 case QAM_256:
5586 status = SetQAM256(state);
5587 break;
5588 default:
5589 status = -EINVAL;
5590 break;
5591 }
5592 if (status < 0)
5593 goto error;
5594
5595 /* Activate SCU to enable SCU commands */
5596 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5597 if (status < 0)
5598 goto error;
5599
5600 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005601 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005602 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5603 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5604 if (status < 0)
5605 goto error;
5606
5607 /* Start processes */
5608 status = MPEGTSStart(state);
5609 if (status < 0)
5610 goto error;
5611 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5612 if (status < 0)
5613 goto error;
5614 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5615 if (status < 0)
5616 goto error;
5617 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5618 if (status < 0)
5619 goto error;
5620
5621 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5622 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5623 if (status < 0)
5624 goto error;
5625
5626 /* update global DRXK data container */
5627/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5628
5629error:
5630 if (status < 0)
5631 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005632 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005633}
5634
Oliver Endrissebc7de22011-07-03 13:49:44 -03005635static int SetQAMStandard(struct drxk_state *state,
5636 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005637{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005638 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005639#ifdef DRXK_QAM_TAPS
5640#define DRXK_QAMA_TAPS_SELECT
5641#include "drxk_filters.h"
5642#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005643#endif
5644
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005645 dprintk(1, "\n");
5646
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005647 /* added antenna switch */
5648 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005649
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005650 /* Ensure correct power-up mode */
5651 status = PowerUpQAM(state);
5652 if (status < 0)
5653 goto error;
5654 /* Reset QAM block */
5655 status = QAMResetQAM(state);
5656 if (status < 0)
5657 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005658
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005659 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005660
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005661 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5662 if (status < 0)
5663 goto error;
5664 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5665 if (status < 0)
5666 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005667
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005668 /* Upload IQM Channel Filter settings by
5669 boot loader from ROM table */
5670 switch (oMode) {
5671 case OM_QAM_ITU_A:
5672 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5673 break;
5674 case OM_QAM_ITU_C:
5675 status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005676 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005677 goto error;
5678 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5679 break;
5680 default:
5681 status = -EINVAL;
5682 }
5683 if (status < 0)
5684 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005685
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005686 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5687 if (status < 0)
5688 goto error;
5689 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5690 if (status < 0)
5691 goto error;
5692 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5693 if (status < 0)
5694 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005695
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005696 status = write16(state, IQM_RC_STRETCH__A, 21);
5697 if (status < 0)
5698 goto error;
5699 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5700 if (status < 0)
5701 goto error;
5702 status = write16(state, IQM_AF_CLP_TH__A, 448);
5703 if (status < 0)
5704 goto error;
5705 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5706 if (status < 0)
5707 goto error;
5708 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5709 if (status < 0)
5710 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005711
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005712 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5713 if (status < 0)
5714 goto error;
5715 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5716 if (status < 0)
5717 goto error;
5718 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5719 if (status < 0)
5720 goto error;
5721 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5722 if (status < 0)
5723 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005724
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005725 /* IQM Impulse Noise Processing Unit */
5726 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5727 if (status < 0)
5728 goto error;
5729 status = write16(state, IQM_CF_DATATH__A, 1000);
5730 if (status < 0)
5731 goto error;
5732 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5733 if (status < 0)
5734 goto error;
5735 status = write16(state, IQM_CF_DET_LCT__A, 0);
5736 if (status < 0)
5737 goto error;
5738 status = write16(state, IQM_CF_WND_LEN__A, 1);
5739 if (status < 0)
5740 goto error;
5741 status = write16(state, IQM_CF_PKDTH__A, 1);
5742 if (status < 0)
5743 goto error;
5744 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5745 if (status < 0)
5746 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005747
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005748 /* turn on IQMAF. Must be done before setAgc**() */
5749 status = SetIqmAf(state, true);
5750 if (status < 0)
5751 goto error;
5752 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5753 if (status < 0)
5754 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005755
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005756 /* IQM will not be reset from here, sync ADC and update/init AGC */
5757 status = ADCSynchronization(state);
5758 if (status < 0)
5759 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005760
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005761 /* Set the FSM step period */
5762 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5763 if (status < 0)
5764 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005765
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005766 /* Halt SCU to enable safe non-atomic accesses */
5767 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5768 if (status < 0)
5769 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005770
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005771 /* No more resets of the IQM, current standard correctly set =>
5772 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005773
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005774 status = InitAGC(state, true);
5775 if (status < 0)
5776 goto error;
5777 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5778 if (status < 0)
5779 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005780
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005781 /* Configure AGC's */
5782 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5783 if (status < 0)
5784 goto error;
5785 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5786 if (status < 0)
5787 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005788
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005789 /* Activate SCU to enable SCU commands */
5790 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5791error:
5792 if (status < 0)
5793 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005794 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005795}
5796
5797static int WriteGPIO(struct drxk_state *state)
5798{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005799 int status;
5800 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005801
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005802 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005803 /* stop lock indicator process */
5804 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5805 if (status < 0)
5806 goto error;
5807
5808 /* Write magic word to enable pdr reg write */
5809 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5810 if (status < 0)
5811 goto error;
5812
5813 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005814 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5815 /* write to io pad configuration register - output mode */
5816 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5817 if (status < 0)
5818 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005819
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005820 /* use corresponding bit in io data output registar */
5821 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5822 if (status < 0)
5823 goto error;
5824 if ((state->m_GPIO & 0x0001) == 0)
5825 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5826 else
5827 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5828 /* write back to io data output register */
5829 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5830 if (status < 0)
5831 goto error;
5832 }
5833 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5834 /* write to io pad configuration register - output mode */
5835 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5836 if (status < 0)
5837 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005838
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005839 /* use corresponding bit in io data output registar */
5840 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5841 if (status < 0)
5842 goto error;
5843 if ((state->m_GPIO & 0x0002) == 0)
5844 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5845 else
5846 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5847 /* write back to io data output register */
5848 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5849 if (status < 0)
5850 goto error;
5851 }
5852 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5853 /* write to io pad configuration register - output mode */
5854 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5855 if (status < 0)
5856 goto error;
5857
5858 /* use corresponding bit in io data output registar */
5859 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5860 if (status < 0)
5861 goto error;
5862 if ((state->m_GPIO & 0x0004) == 0)
5863 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5864 else
5865 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5866 /* write back to io data output register */
5867 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5868 if (status < 0)
5869 goto error;
5870 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005871 }
5872 /* Write magic word to disable pdr reg write */
5873 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5874error:
5875 if (status < 0)
5876 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005877 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005878}
5879
5880static int SwitchAntennaToQAM(struct drxk_state *state)
5881{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005882 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005883 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005884
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005885 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005886
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005887 if (!state->antenna_gpio)
5888 return 0;
5889
5890 gpio_state = state->m_GPIO & state->antenna_gpio;
5891
5892 if (state->antenna_dvbt ^ gpio_state) {
5893 /* Antenna is on DVB-T mode. Switch */
5894 if (state->antenna_dvbt)
5895 state->m_GPIO &= ~state->antenna_gpio;
5896 else
5897 state->m_GPIO |= state->antenna_gpio;
5898 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005899 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005900 if (status < 0)
5901 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005902 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005903}
5904
5905static int SwitchAntennaToDVBT(struct drxk_state *state)
5906{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005907 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005908 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005909
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005910 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005911
5912 if (!state->antenna_gpio)
5913 return 0;
5914
5915 gpio_state = state->m_GPIO & state->antenna_gpio;
5916
5917 if (!(state->antenna_dvbt ^ gpio_state)) {
5918 /* Antenna is on DVB-C mode. Switch */
5919 if (state->antenna_dvbt)
5920 state->m_GPIO |= state->antenna_gpio;
5921 else
5922 state->m_GPIO &= ~state->antenna_gpio;
5923 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005924 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005925 if (status < 0)
5926 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005927 return status;
5928}
5929
5930
5931static int PowerDownDevice(struct drxk_state *state)
5932{
5933 /* Power down to requested mode */
5934 /* Backup some register settings */
5935 /* Set pins with possible pull-ups connected to them in input mode */
5936 /* Analog power down */
5937 /* ADC power down */
5938 /* Power down device */
5939 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005940
5941 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005942 if (state->m_bPDownOpenBridge) {
5943 /* Open I2C bridge before power down of DRXK */
5944 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005945 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005946 goto error;
5947 }
5948 /* driver 0.9.0 */
5949 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005950 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005951 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005952
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005953 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5954 if (status < 0)
5955 goto error;
5956 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5957 if (status < 0)
5958 goto error;
5959 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5960 status = HI_CfgCommand(state);
5961error:
5962 if (status < 0)
5963 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5964
5965 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005966}
5967
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005968static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005969{
5970 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005971 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005972
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005973 dprintk(1, "\n");
5974
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005975 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5976 if (err < 0) {
5977 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005978 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005979 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005980 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005981 return err;
5982 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005983 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005984 release_firmware(fw);
5985 return err;
5986}
5987
5988static int init_drxk(struct drxk_state *state)
5989{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005990 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005991 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005992 u16 driverVersion;
5993
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005994 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005995 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005996 status = PowerUpDevice(state);
5997 if (status < 0)
5998 goto error;
5999 status = DRXX_Open(state);
6000 if (status < 0)
6001 goto error;
6002 /* Soft reset of OFDM-, sys- and osc-clockdomain */
6003 status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
6004 if (status < 0)
6005 goto error;
6006 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6007 if (status < 0)
6008 goto error;
6009 /* TODO is this needed, if yes how much delay in worst case scenario */
6010 msleep(1);
6011 state->m_DRXK_A3_PATCH_CODE = true;
6012 status = GetDeviceCapabilities(state);
6013 if (status < 0)
6014 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006015
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006016 /* Bridge delay, uses oscilator clock */
6017 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6018 /* SDA brdige delay */
6019 state->m_HICfgBridgeDelay =
6020 (u16) ((state->m_oscClockFreq / 1000) *
6021 HI_I2C_BRIDGE_DELAY) / 1000;
6022 /* Clipping */
6023 if (state->m_HICfgBridgeDelay >
6024 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006025 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006026 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6027 }
6028 /* SCL bridge delay, same as SDA for now */
6029 state->m_HICfgBridgeDelay +=
6030 state->m_HICfgBridgeDelay <<
6031 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006032
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006033 status = InitHI(state);
6034 if (status < 0)
6035 goto error;
6036 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006037#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006038 if (!(state->m_DRXK_A1_ROM_CODE)
6039 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006040#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006041 {
6042 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6043 if (status < 0)
6044 goto error;
6045 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006046
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006047 /* disable MPEG port */
6048 status = MPEGTSDisable(state);
6049 if (status < 0)
6050 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006051
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006052 /* Stop AUD and SCU */
6053 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6054 if (status < 0)
6055 goto error;
6056 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6057 if (status < 0)
6058 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006059
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006060 /* enable token-ring bus through OFDM block for possible ucode upload */
6061 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6062 if (status < 0)
6063 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006064
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006065 /* include boot loader section */
6066 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6067 if (status < 0)
6068 goto error;
6069 status = BLChainCmd(state, 0, 6, 100);
6070 if (status < 0)
6071 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006072
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006073 if (!state->microcode_name)
6074 load_microcode(state, "drxk_a3.mc");
6075 else
6076 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006077
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006078 /* disable token-ring bus through OFDM block for possible ucode upload */
6079 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6080 if (status < 0)
6081 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006082
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006083 /* Run SCU for a little while to initialize microcode version numbers */
6084 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6085 if (status < 0)
6086 goto error;
6087 status = DRXX_Open(state);
6088 if (status < 0)
6089 goto error;
6090 /* added for test */
6091 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006092
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006093 powerMode = DRXK_POWER_DOWN_OFDM;
6094 status = CtrlPowerMode(state, &powerMode);
6095 if (status < 0)
6096 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006097
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006098 /* Stamp driver version number in SCU data RAM in BCD code
6099 Done to enable field application engineers to retreive drxdriver version
6100 via I2C from SCU RAM.
6101 Not using SCU command interface for SCU register access since no
6102 microcode may be present.
6103 */
6104 driverVersion =
6105 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6106 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6107 ((DRXK_VERSION_MAJOR % 10) << 4) +
6108 (DRXK_VERSION_MINOR % 10);
6109 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6110 if (status < 0)
6111 goto error;
6112 driverVersion =
6113 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6114 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6115 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6116 (DRXK_VERSION_PATCH % 10);
6117 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6118 if (status < 0)
6119 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006120
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006121 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6122 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6123 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006124
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006125 /* Dirty fix of default values for ROM/PATCH microcode
6126 Dirty because this fix makes it impossible to setup suitable values
6127 before calling DRX_Open. This solution requires changes to RF AGC speed
6128 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006129
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006130 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006131
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006132 /* Reset driver debug flags to 0 */
6133 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6134 if (status < 0)
6135 goto error;
6136 /* driver 0.9.0 */
6137 /* Setup FEC OC:
6138 NOTE: No more full FEC resets allowed afterwards!! */
6139 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6140 if (status < 0)
6141 goto error;
6142 /* MPEGTS functions are still the same */
6143 status = MPEGTSDtoInit(state);
6144 if (status < 0)
6145 goto error;
6146 status = MPEGTSStop(state);
6147 if (status < 0)
6148 goto error;
6149 status = MPEGTSConfigurePolarity(state);
6150 if (status < 0)
6151 goto error;
6152 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6153 if (status < 0)
6154 goto error;
6155 /* added: configure GPIO */
6156 status = WriteGPIO(state);
6157 if (status < 0)
6158 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006159
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006160 state->m_DrxkState = DRXK_STOPPED;
6161
6162 if (state->m_bPowerDown) {
6163 status = PowerDownDevice(state);
6164 if (status < 0)
6165 goto error;
6166 state->m_DrxkState = DRXK_POWERED_DOWN;
6167 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006168 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006169 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006170error:
6171 if (status < 0)
6172 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006173
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006174 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006175}
6176
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006177static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006178{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006179 struct drxk_state *state = fe->demodulator_priv;
6180
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006181 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006182 kfree(state);
6183}
6184
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006185static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006186{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006187 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006188
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006189 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006190 ShutDown(state);
6191 mutex_unlock(&state->ctlock);
6192 return 0;
6193}
6194
Oliver Endrissebc7de22011-07-03 13:49:44 -03006195static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006196{
6197 struct drxk_state *state = fe->demodulator_priv;
6198
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006199 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006200 return ConfigureI2CBridge(state, enable ? true : false);
6201}
6202
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006203static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006204{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006205 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
6206 u32 delsys = p->delivery_system;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006207 struct drxk_state *state = fe->demodulator_priv;
6208 u32 IF;
6209
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006210 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006211
6212 if (!fe->ops.tuner_ops.get_if_frequency) {
6213 printk(KERN_ERR
6214 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6215 return -EINVAL;
6216 }
6217
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006218 if (fe->ops.i2c_gate_ctrl)
6219 fe->ops.i2c_gate_ctrl(fe, 1);
6220 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006221 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006222 if (fe->ops.i2c_gate_ctrl)
6223 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006224 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006225
6226 switch (delsys) {
6227 case SYS_DVBC_ANNEX_A:
6228 case SYS_DVBC_ANNEX_C:
6229 if (!state->m_hasDVBC)
6230 return -EINVAL;
6231 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6232 if (state->m_itut_annex_c)
6233 SetOperationMode(state, OM_QAM_ITU_C);
6234 else
6235 SetOperationMode(state, OM_QAM_ITU_A);
6236 break;
6237 state->m_itut_annex_c = true;
6238 break;
6239 case SYS_DVBT:
6240 if (!state->m_hasDVBT)
6241 return -EINVAL;
6242 SetOperationMode(state, OM_DVBT);
6243 break;
6244 default:
6245 return -EINVAL;
6246 }
6247
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006248 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006249 Start(state, 0, IF);
6250
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006251 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006252
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006253 return 0;
6254}
6255
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006256static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6257{
6258 struct drxk_state *state = fe->demodulator_priv;
6259 u32 stat;
6260
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006261 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006262 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006263 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006264 if (stat == MPEG_LOCK)
6265 *status |= 0x1f;
6266 if (stat == FEC_LOCK)
6267 *status |= 0x0f;
6268 if (stat == DEMOD_LOCK)
6269 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006270 return 0;
6271}
6272
6273static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6274{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006275 dprintk(1, "\n");
6276
Oliver Endrissebc7de22011-07-03 13:49:44 -03006277 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006278 return 0;
6279}
6280
Oliver Endrissebc7de22011-07-03 13:49:44 -03006281static int drxk_read_signal_strength(struct dvb_frontend *fe,
6282 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006283{
6284 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006285 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006286
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006287 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006288 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006289 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006290 return 0;
6291}
6292
6293static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6294{
6295 struct drxk_state *state = fe->demodulator_priv;
6296 s32 snr2;
6297
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006298 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006299 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006300 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006301 return 0;
6302}
6303
6304static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6305{
6306 struct drxk_state *state = fe->demodulator_priv;
6307 u16 err;
6308
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006309 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006310 DVBTQAMGetAccPktErr(state, &err);
6311 *ucblocks = (u32) err;
6312 return 0;
6313}
6314
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006315static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006316 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006317{
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006318 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006319
6320 dprintk(1, "\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006321 switch (p->delivery_system) {
6322 case SYS_DVBC_ANNEX_A:
6323 case SYS_DVBC_ANNEX_C:
6324 sets->min_delay_ms = 3000;
6325 sets->max_drift = 0;
6326 sets->step_size = 0;
6327 return 0;
6328 default:
6329 /*
6330 * For DVB-T, let it use the default DVB core way, that is:
6331 * fepriv->step_size = fe->ops.info.frequency_stepsize * 2
6332 */
6333 return -EINVAL;
6334 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006335}
6336
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006337static struct dvb_frontend_ops drxk_ops = {
6338 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006339 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006340 .name = "DRXK",
6341 .frequency_min = 47000000,
6342 .frequency_max = 865000000,
6343 /* For DVB-C */
6344 .symbol_rate_min = 870000,
6345 .symbol_rate_max = 11700000,
6346 /* For DVB-T */
6347 .frequency_stepsize = 166667,
6348
6349 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6350 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6351 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6352 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6353 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6354 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6355 },
6356
6357 .release = drxk_release,
6358 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006359 .i2c_gate_ctrl = drxk_gate_ctrl,
6360
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006361 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006362 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006363
6364 .read_status = drxk_read_status,
6365 .read_ber = drxk_read_ber,
6366 .read_signal_strength = drxk_read_signal_strength,
6367 .read_snr = drxk_read_snr,
6368 .read_ucblocks = drxk_read_ucblocks,
6369};
6370
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006371struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006372 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006373{
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006374 int n;
6375
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006376 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006377 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006378
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006379 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006380 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006381 if (!state)
6382 return NULL;
6383
Oliver Endrissebc7de22011-07-03 13:49:44 -03006384 state->i2c = i2c;
6385 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006386 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006387 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006388 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006389 state->antenna_gpio = config->antenna_gpio;
6390 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006391 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006392
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006393 if (config->parallel_ts)
6394 state->m_enableParallel = true;
6395 else
6396 state->m_enableParallel = false;
6397
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006398 /* NOTE: as more UIO bits will be used, add them to the mask */
6399 state->UIO_mask = config->antenna_gpio;
6400
6401 /* Default gpio to DVB-C */
6402 if (!state->antenna_dvbt && state->antenna_gpio)
6403 state->m_GPIO |= state->antenna_gpio;
6404 else
6405 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006406
6407 mutex_init(&state->mutex);
6408 mutex_init(&state->ctlock);
6409
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006410 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6411 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006412
6413 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006414 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006415 goto error;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006416
6417 /* Initialize the supported delivery systems */
6418 n = 0;
6419 if (state->m_hasDVBC) {
6420 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6421 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6422 strlcat(state->frontend.ops.info.name, " DVB-C",
6423 sizeof(state->frontend.ops.info.name));
6424 }
6425 if (state->m_hasDVBT) {
6426 state->frontend.ops.delsys[n++] = SYS_DVBT;
6427 strlcat(state->frontend.ops.info.name, " DVB-T",
6428 sizeof(state->frontend.ops.info.name));
6429 }
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006430
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006431 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006432 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006433
6434error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006435 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006436 kfree(state);
6437 return NULL;
6438}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006439EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006440
6441MODULE_DESCRIPTION("DRX-K driver");
6442MODULE_AUTHOR("Ralph Metzler");
6443MODULE_LICENSE("GPL");