blob: bb8627ffae73edcd13d53058ae5a152fa64bcf75 [file] [log] [blame]
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001/*
2 * drxk_hard: DRX-K DVB-C/T demodulator driver
3 *
4 * Copyright (C) 2010-2011 Digital Devices GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/firmware.h>
30#include <linux/i2c.h>
31#include <linux/version.h>
32#include <asm/div64.h>
33
34#include "dvb_frontend.h"
35#include "drxk.h"
36#include "drxk_hard.h"
37
38static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
39static int PowerDownQAM(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030040static int SetDVBTStandard(struct drxk_state *state,
41 enum OperationMode oMode);
42static int SetQAMStandard(struct drxk_state *state,
43 enum OperationMode oMode);
44static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
Ralph Metzler43dd07f2011-07-03 13:42:18 -030045 s32 tunerFreqOffset);
Oliver Endrissebc7de22011-07-03 13:49:44 -030046static int SetDVBTStandard(struct drxk_state *state,
47 enum OperationMode oMode);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030048static int DVBTStart(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030049static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
50 s32 tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030051static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
52static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
53static int SwitchAntennaToQAM(struct drxk_state *state);
54static int SwitchAntennaToDVBT(struct drxk_state *state);
55
56static bool IsDVBT(struct drxk_state *state)
57{
58 return state->m_OperationMode == OM_DVBT;
59}
60
61static bool IsQAM(struct drxk_state *state)
62{
63 return state->m_OperationMode == OM_QAM_ITU_A ||
Oliver Endrissebc7de22011-07-03 13:49:44 -030064 state->m_OperationMode == OM_QAM_ITU_B ||
65 state->m_OperationMode == OM_QAM_ITU_C;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030066}
67
68bool IsA1WithPatchCode(struct drxk_state *state)
69{
70 return state->m_DRXK_A1_PATCH_CODE;
71}
72
73bool IsA1WithRomCode(struct drxk_state *state)
74{
75 return state->m_DRXK_A1_ROM_CODE;
76}
77
78#define NOA1ROM 0
79
Ralph Metzler43dd07f2011-07-03 13:42:18 -030080#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
81#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
82
83#define DEFAULT_MER_83 165
84#define DEFAULT_MER_93 250
85
86#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
87#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
88#endif
89
90#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
91#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
92#endif
93
94#ifndef DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH
95#define DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH (0x06)
96#endif
97
98#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
99#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
100
101#ifndef DRXK_KI_RAGC_ATV
102#define DRXK_KI_RAGC_ATV 4
103#endif
104#ifndef DRXK_KI_IAGC_ATV
105#define DRXK_KI_IAGC_ATV 6
106#endif
107#ifndef DRXK_KI_DAGC_ATV
108#define DRXK_KI_DAGC_ATV 7
109#endif
110
111#ifndef DRXK_KI_RAGC_QAM
112#define DRXK_KI_RAGC_QAM 3
113#endif
114#ifndef DRXK_KI_IAGC_QAM
115#define DRXK_KI_IAGC_QAM 4
116#endif
117#ifndef DRXK_KI_DAGC_QAM
118#define DRXK_KI_DAGC_QAM 7
119#endif
120#ifndef DRXK_KI_RAGC_DVBT
121#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
122#endif
123#ifndef DRXK_KI_IAGC_DVBT
124#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
125#endif
126#ifndef DRXK_KI_DAGC_DVBT
127#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
128#endif
129
130#ifndef DRXK_AGC_DAC_OFFSET
131#define DRXK_AGC_DAC_OFFSET (0x800)
132#endif
133
134#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
135#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
136#endif
137
138#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
139#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
140#endif
141
142#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
143#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
144#endif
145
146#ifndef DRXK_QAM_SYMBOLRATE_MAX
147#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
148#endif
149
150#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
151#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
152#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
153#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
154#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
155#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
156#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
157#define DRXK_BL_ROM_OFFSET_UCODE 0
158
159#define DRXK_BLC_TIMEOUT 100
160
161#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
162#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
163
164#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
165
166#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
167#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
168#endif
169
170#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
171#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
172#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
173#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
174#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
175
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300176static unsigned int debug;
177module_param(debug, int, 0644);
178MODULE_PARM_DESC(debug, "enable debug messages");
179
180#define dprintk(level, fmt, arg...) do { \
181if (debug >= level) \
182 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
183} while (0)
184
185
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300186static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300187{
188 u64 tmp64;
189
Oliver Endrissebc7de22011-07-03 13:49:44 -0300190 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300191 do_div(tmp64, c);
192
193 return (u32) tmp64;
194}
195
196inline u32 Frac28a(u32 a, u32 c)
197{
198 int i = 0;
199 u32 Q1 = 0;
200 u32 R0 = 0;
201
Oliver Endrissebc7de22011-07-03 13:49:44 -0300202 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
203 Q1 = a / c; /* integer part, only the 4 least significant bits
204 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300205
206 /* division using radix 16, 7 nibbles in the result */
207 for (i = 0; i < 7; i++) {
208 Q1 = (Q1 << 4) | (R0 / c);
209 R0 = (R0 % c) << 4;
210 }
211 /* rounding */
212 if ((R0 >> 3) >= c)
213 Q1++;
214
215 return Q1;
216}
217
218static u32 Log10Times100(u32 x)
219{
220 static const u8 scale = 15;
221 static const u8 indexWidth = 5;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300222 u8 i = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300223 u32 y = 0;
224 u32 d = 0;
225 u32 k = 0;
226 u32 r = 0;
227 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300228 log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
229 0 <= n < ((1<<INDEXWIDTH)+1)
230 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300231
232 static const u32 log2lut[] = {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300233 0, /* 0.000000 */
234 290941, /* 290941.300628 */
235 573196, /* 573196.476418 */
236 847269, /* 847269.179851 */
237 1113620, /* 1113620.489452 */
238 1372674, /* 1372673.576986 */
239 1624818, /* 1624817.752104 */
240 1870412, /* 1870411.981536 */
241 2109788, /* 2109787.962654 */
242 2343253, /* 2343252.817465 */
243 2571091, /* 2571091.461923 */
244 2793569, /* 2793568.696416 */
245 3010931, /* 3010931.055901 */
246 3223408, /* 3223408.452106 */
247 3431216, /* 3431215.635215 */
248 3634553, /* 3634553.498355 */
249 3833610, /* 3833610.244726 */
250 4028562, /* 4028562.434393 */
251 4219576, /* 4219575.925308 */
252 4406807, /* 4406806.721144 */
253 4590402, /* 4590401.736809 */
254 4770499, /* 4770499.491025 */
255 4947231, /* 4947230.734179 */
256 5120719, /* 5120719.018555 */
257 5291081, /* 5291081.217197 */
258 5458428, /* 5458427.996830 */
259 5622864, /* 5622864.249668 */
260 5784489, /* 5784489.488298 */
261 5943398, /* 5943398.207380 */
262 6099680, /* 6099680.215452 */
263 6253421, /* 6253420.939751 */
264 6404702, /* 6404701.706649 */
265 6553600, /* 6553600.000000 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300266 };
267
268
269 if (x == 0)
Oliver Endrissebc7de22011-07-03 13:49:44 -0300270 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300271
272 /* Scale x (normalize) */
273 /* computing y in log(x/y) = log(x) - log(y) */
274 if ((x & ((0xffffffff) << (scale + 1))) == 0) {
275 for (k = scale; k > 0; k--) {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300276 if (x & (((u32) 1) << scale))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300277 break;
278 x <<= 1;
279 }
280 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300281 for (k = scale; k < 31; k++) {
282 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300283 break;
284 x >>= 1;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300285 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300286 }
287 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300288 Now x has binary point between bit[scale] and bit[scale-1]
289 and 1.0 <= x < 2.0 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300290
291 /* correction for divison: log(x) = log(x/y)+log(y) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300292 y = k * ((((u32) 1) << scale) * 200);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300293
294 /* remove integer part */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300295 x &= ((((u32) 1) << scale) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300296 /* get index */
297 i = (u8) (x >> (scale - indexWidth));
298 /* compute delta (x - a) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300299 d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300300 /* compute log, multiplication (d* (..)) must be within range ! */
301 y += log2lut[i] +
Oliver Endrissebc7de22011-07-03 13:49:44 -0300302 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300303 /* Conver to log10() */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300304 y /= 108853; /* (log2(10) << scale) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300305 r = (y >> 1);
306 /* rounding */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300307 if (y & ((u32) 1))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300308 r++;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300309 return r;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300310}
311
312/****************************************************************************/
313/* I2C **********************************************************************/
314/****************************************************************************/
315
316static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val)
317{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300318 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
319 .buf = val, .len = 1}
320 };
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300321
322 return i2c_transfer(adapter, msgs, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300323}
324
325static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
326{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300327 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300328 struct i2c_msg msg = {
329 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300330
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300331 dprintk(3, ":");
332 if (debug > 2) {
333 int i;
334 for (i = 0; i < len; i++)
335 printk(KERN_CONT " %02x", data[i]);
336 printk(KERN_CONT "\n");
337 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300338 status = i2c_transfer(adap, &msg, 1);
339 if (status >= 0 && status != 1)
340 status = -EIO;
341
342 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300343 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300344
345 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300346}
347
348static int i2c_read(struct i2c_adapter *adap,
349 u8 adr, u8 *msg, int len, u8 *answ, int alen)
350{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300351 int status;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300352 struct i2c_msg msgs[2] = {
353 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300354 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300355 {.addr = adr, .flags = I2C_M_RD,
356 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300357 };
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300358 dprintk(3, ":");
359 if (debug > 2) {
360 int i;
361 for (i = 0; i < len; i++)
362 printk(KERN_CONT " %02x", msg[i]);
363 printk(KERN_CONT "\n");
364 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300365 status = i2c_transfer(adap, msgs, 2);
366 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300367 if (debug > 2)
368 printk(KERN_CONT ": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300369 if (status >= 0)
370 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300371
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300372 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300373 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300374 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300375 if (debug > 2) {
376 int i;
377 printk(KERN_CONT ": Read ");
378 for (i = 0; i < len; i++)
379 printk(KERN_CONT " %02x", msg[i]);
380 printk(KERN_CONT "\n");
381 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300382 return 0;
383}
384
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300385static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300386{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300387 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300388 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300389
390 if (state->single_master)
391 flags |= 0xC0;
392
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300393 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
394 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
395 mm1[1] = ((reg >> 16) & 0xFF);
396 mm1[2] = ((reg >> 24) & 0xFF) | flags;
397 mm1[3] = ((reg >> 7) & 0xFF);
398 len = 4;
399 } else {
400 mm1[0] = ((reg << 1) & 0xFF);
401 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
402 len = 2;
403 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300404 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300405 status = i2c_read(state->i2c, adr, mm1, len, mm2, 2);
406 if (status < 0)
407 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300408 if (data)
409 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300410
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300411 return 0;
412}
413
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300414static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300415{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300416 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300417}
418
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300419static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300420{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300421 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300422 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300423
424 if (state->single_master)
425 flags |= 0xC0;
426
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300427 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
428 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
429 mm1[1] = ((reg >> 16) & 0xFF);
430 mm1[2] = ((reg >> 24) & 0xFF) | flags;
431 mm1[3] = ((reg >> 7) & 0xFF);
432 len = 4;
433 } else {
434 mm1[0] = ((reg << 1) & 0xFF);
435 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
436 len = 2;
437 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300438 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300439 status = i2c_read(state->i2c, adr, mm1, len, mm2, 4);
440 if (status < 0)
441 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300442 if (data)
443 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300444 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300445
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300446 return 0;
447}
448
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300449static int read32(struct drxk_state *state, u32 reg, u32 *data)
450{
451 return read32_flags(state, reg, data, 0);
452}
453
454static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300455{
456 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300457
458 if (state->single_master)
459 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300460 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
461 mm[0] = (((reg << 1) & 0xFF) | 0x01);
462 mm[1] = ((reg >> 16) & 0xFF);
463 mm[2] = ((reg >> 24) & 0xFF) | flags;
464 mm[3] = ((reg >> 7) & 0xFF);
465 len = 4;
466 } else {
467 mm[0] = ((reg << 1) & 0xFF);
468 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
469 len = 2;
470 }
471 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300472 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300473
474 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300475 return i2c_write(state->i2c, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300476}
477
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300478static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300479{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300480 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300481}
482
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300483static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300484{
485 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300486
487 if (state->single_master)
488 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300489 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
490 mm[0] = (((reg << 1) & 0xFF) | 0x01);
491 mm[1] = ((reg >> 16) & 0xFF);
492 mm[2] = ((reg >> 24) & 0xFF) | flags;
493 mm[3] = ((reg >> 7) & 0xFF);
494 len = 4;
495 } else {
496 mm[0] = ((reg << 1) & 0xFF);
497 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
498 len = 2;
499 }
500 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300501 mm[len + 1] = (data >> 8) & 0xff;
502 mm[len + 2] = (data >> 16) & 0xff;
503 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300504 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300505
506 return i2c_write(state->i2c, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300507}
508
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300509static int write32(struct drxk_state *state, u32 reg, u32 data)
510{
511 return write32_flags(state, reg, data, 0);
512}
513
514static int write_block(struct drxk_state *state, u32 Address,
515 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300516{
517 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300518 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300519
520 if (state->single_master)
521 Flags |= 0xC0;
522
Oliver Endrissebc7de22011-07-03 13:49:44 -0300523 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300524 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300525 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300526 u8 *AdrBuf = &state->Chunk[0];
527 u32 AdrLength = 0;
528
Oliver Endrissebc7de22011-07-03 13:49:44 -0300529 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
530 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
531 AdrBuf[1] = ((Address >> 16) & 0xFF);
532 AdrBuf[2] = ((Address >> 24) & 0xFF);
533 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300534 AdrBuf[2] |= Flags;
535 AdrLength = 4;
536 if (Chunk == state->m_ChunkSize)
537 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300538 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300539 AdrBuf[0] = ((Address << 1) & 0xFF);
540 AdrBuf[1] = (((Address >> 16) & 0x0F) |
541 ((Address >> 18) & 0xF0));
542 AdrLength = 2;
543 }
544 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300545 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
546 if (debug > 1) {
547 int i;
548 if (pBlock)
549 for (i = 0; i < Chunk; i++)
550 printk(KERN_CONT " %02x", pBlock[i]);
551 printk(KERN_CONT "\n");
552 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300553 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300554 &state->Chunk[0], Chunk + AdrLength);
555 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300556 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
557 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300558 break;
559 }
560 pBlock += Chunk;
561 Address += (Chunk >> 1);
562 BlkSize -= Chunk;
563 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300564 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300565}
566
567#ifndef DRXK_MAX_RETRIES_POWERUP
568#define DRXK_MAX_RETRIES_POWERUP 20
569#endif
570
571int PowerUpDevice(struct drxk_state *state)
572{
573 int status;
574 u8 data = 0;
575 u16 retryCount = 0;
576
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300577 dprintk(1, "\n");
578
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300579 status = i2c_read1(state->i2c, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300580 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300581 do {
582 data = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300583 status = i2c_write(state->i2c, state->demod_address,
584 &data, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300585 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300586 retryCount++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300587 if (status < 0)
588 continue;
589 status = i2c_read1(state->i2c, state->demod_address,
590 &data);
591 } while (status < 0 &&
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300592 (retryCount < DRXK_MAX_RETRIES_POWERUP));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300593 if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
594 goto error;
595 }
596
597 /* Make sure all clk domains are active */
598 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
599 if (status < 0)
600 goto error;
601 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
602 if (status < 0)
603 goto error;
604 /* Enable pll lock tests */
605 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
606 if (status < 0)
607 goto error;
608
609 state->m_currentPowerMode = DRX_POWER_UP;
610
611error:
612 if (status < 0)
613 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
614
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300615 return status;
616}
617
618
619static int init_state(struct drxk_state *state)
620{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -0300621 /*
622 * FIXME: most (all?) of the values bellow should be moved into
623 * struct drxk_config, as they are probably board-specific
624 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300625 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
626 u32 ulVSBIfAgcOutputLevel = 0;
627 u32 ulVSBIfAgcMinLevel = 0;
628 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
629 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300630
Oliver Endrissebc7de22011-07-03 13:49:44 -0300631 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
632 u32 ulVSBRfAgcOutputLevel = 0;
633 u32 ulVSBRfAgcMinLevel = 0;
634 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
635 u32 ulVSBRfAgcSpeed = 3;
636 u32 ulVSBRfAgcTop = 9500;
637 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300638
Oliver Endrissebc7de22011-07-03 13:49:44 -0300639 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
640 u32 ulATVIfAgcOutputLevel = 0;
641 u32 ulATVIfAgcMinLevel = 0;
642 u32 ulATVIfAgcMaxLevel = 0;
643 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300644
Oliver Endrissebc7de22011-07-03 13:49:44 -0300645 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
646 u32 ulATVRfAgcOutputLevel = 0;
647 u32 ulATVRfAgcMinLevel = 0;
648 u32 ulATVRfAgcMaxLevel = 0;
649 u32 ulATVRfAgcTop = 9500;
650 u32 ulATVRfAgcCutOffCurrent = 4000;
651 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300652
653 u32 ulQual83 = DEFAULT_MER_83;
654 u32 ulQual93 = DEFAULT_MER_93;
655
656 u32 ulDVBTStaticTSClock = 1;
657 u32 ulDVBCStaticTSClock = 1;
658
659 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
660 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
661
662 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
663 /* io_pad_cfg_mode output mode is drive always */
664 /* io_pad_cfg_drive is set to power 2 (23 mA) */
665 u32 ulGPIOCfg = 0x0113;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300666 u32 ulGPIO = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300667 u32 ulSerialMode = 1;
668 u32 ulInvertTSClock = 0;
669 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
670 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
671 u32 ulDVBTBitrate = 50000000;
672 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
673
674 u32 ulInsertRSByte = 0;
675
676 u32 ulRfMirror = 1;
677 u32 ulPowerDown = 0;
678
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300679 dprintk(1, "\n");
680
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300681 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300682 state->m_hasDVBT = false;
683 state->m_hasDVBC = false;
684 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300685 state->m_hasOOB = false;
686 state->m_hasAudio = false;
687
688 state->m_ChunkSize = 124;
689
690 state->m_oscClockFreq = 0;
691 state->m_smartAntInverted = false;
692 state->m_bPDownOpenBridge = false;
693
694 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300695 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300696 /* Timing div, 250ns/Psys */
697 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
698 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
699 HI_I2C_DELAY) / 1000;
700 /* Clipping */
701 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
702 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
703 state->m_HICfgWakeUpKey = (state->demod_address << 1);
704 /* port/bridge/power down ctrl */
705 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
706
707 state->m_bPowerDown = (ulPowerDown != 0);
708
709 state->m_DRXK_A1_PATCH_CODE = false;
710 state->m_DRXK_A1_ROM_CODE = false;
711 state->m_DRXK_A2_ROM_CODE = false;
712 state->m_DRXK_A3_ROM_CODE = false;
713 state->m_DRXK_A2_PATCH_CODE = false;
714 state->m_DRXK_A3_PATCH_CODE = false;
715
716 /* Init AGC and PGA parameters */
717 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300718 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
719 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
720 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
721 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
722 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300723 state->m_vsbPgaCfg = 140;
724
725 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300726 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
727 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
728 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
729 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
730 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
731 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
732 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
733 state->m_vsbPreSawCfg.reference = 0x07;
734 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300735
736 state->m_Quality83percent = DEFAULT_MER_83;
737 state->m_Quality93percent = DEFAULT_MER_93;
738 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
739 state->m_Quality83percent = ulQual83;
740 state->m_Quality93percent = ulQual93;
741 }
742
743 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300744 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
745 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
746 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
747 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
748 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300749
750 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300751 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
752 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
753 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
754 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
755 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
756 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
757 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
758 state->m_atvPreSawCfg.reference = 0x04;
759 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300760
761
762 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300763 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
764 state->m_dvbtRfAgcCfg.outputLevel = 0;
765 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
766 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
767 state->m_dvbtRfAgcCfg.top = 0x2100;
768 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
769 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300770
771
772 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300773 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
774 state->m_dvbtIfAgcCfg.outputLevel = 0;
775 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
776 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
777 state->m_dvbtIfAgcCfg.top = 13424;
778 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
779 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300780 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300781 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
782 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300783
Oliver Endrissebc7de22011-07-03 13:49:44 -0300784 state->m_dvbtPreSawCfg.reference = 4;
785 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300786
787 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300788 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
789 state->m_qamRfAgcCfg.outputLevel = 0;
790 state->m_qamRfAgcCfg.minOutputLevel = 6023;
791 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
792 state->m_qamRfAgcCfg.top = 0x2380;
793 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
794 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300795
796 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300797 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
798 state->m_qamIfAgcCfg.outputLevel = 0;
799 state->m_qamIfAgcCfg.minOutputLevel = 0;
800 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
801 state->m_qamIfAgcCfg.top = 0x0511;
802 state->m_qamIfAgcCfg.cutOffCurrent = 0;
803 state->m_qamIfAgcCfg.speed = 3;
804 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300805 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
806
Oliver Endrissebc7de22011-07-03 13:49:44 -0300807 state->m_qamPgaCfg = 140;
808 state->m_qamPreSawCfg.reference = 4;
809 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300810
811 state->m_OperationMode = OM_NONE;
812 state->m_DrxkState = DRXK_UNINITIALIZED;
813
814 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300815 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
816 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
817 state->m_enableParallel = true; /* If TRUE;
818 parallel out otherwise serial */
819 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
820 state->m_invertERR = false; /* If TRUE; invert ERR signal */
821 state->m_invertSTR = false; /* If TRUE; invert STR signals */
822 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
823 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300824 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300825 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300826 /* If TRUE; static MPEG clockrate will be used;
827 otherwise clockrate will adapt to the bitrate of the TS */
828
829 state->m_DVBTBitrate = ulDVBTBitrate;
830 state->m_DVBCBitrate = ulDVBCBitrate;
831
832 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
833 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
834
835 /* Maximum bitrate in b/s in case static clockrate is selected */
836 state->m_mpegTsStaticBitrate = 19392658;
837 state->m_disableTEIhandling = false;
838
839 if (ulInsertRSByte)
840 state->m_insertRSByte = true;
841
842 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
843 if (ulMpegLockTimeOut < 10000)
844 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
845 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
846 if (ulDemodLockTimeOut < 10000)
847 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
848
Oliver Endrissebc7de22011-07-03 13:49:44 -0300849 /* QAM defaults */
850 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300851 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300852 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
853 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300854
855 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
856 state->m_agcFastClipCtrlDelay = 0;
857
858 state->m_GPIOCfg = (ulGPIOCfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300859
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300860 state->m_bPowerDown = false;
861 state->m_currentPowerMode = DRX_POWER_DOWN;
862
863 state->m_enableParallel = (ulSerialMode == 0);
864
865 state->m_rfmirror = (ulRfMirror == 0);
866 state->m_IfAgcPol = false;
867 return 0;
868}
869
870static int DRXX_Open(struct drxk_state *state)
871{
872 int status = 0;
873 u32 jtag = 0;
874 u16 bid = 0;
875 u16 key = 0;
876
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300877 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300878 /* stop lock indicator process */
879 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
880 if (status < 0)
881 goto error;
882 /* Check device id */
883 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
884 if (status < 0)
885 goto error;
886 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
887 if (status < 0)
888 goto error;
889 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
890 if (status < 0)
891 goto error;
892 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
893 if (status < 0)
894 goto error;
895 status = write16(state, SIO_TOP_COMM_KEY__A, key);
896error:
897 if (status < 0)
898 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300899 return status;
900}
901
902static int GetDeviceCapabilities(struct drxk_state *state)
903{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300904 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300905 u32 sioTopJtagidLo = 0;
906 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300907 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300908
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300909 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300910
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300911 /* driver 0.9.0 */
912 /* stop lock indicator process */
913 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
914 if (status < 0)
915 goto error;
916 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
917 if (status < 0)
918 goto error;
919 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
920 if (status < 0)
921 goto error;
922 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
923 if (status < 0)
924 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300925
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300926 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
927 case 0:
928 /* ignore (bypass ?) */
929 break;
930 case 1:
931 /* 27 MHz */
932 state->m_oscClockFreq = 27000;
933 break;
934 case 2:
935 /* 20.25 MHz */
936 state->m_oscClockFreq = 20250;
937 break;
938 case 3:
939 /* 4 MHz */
940 state->m_oscClockFreq = 20250;
941 break;
942 default:
943 printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
944 return -EINVAL;
945 }
946 /*
947 Determine device capabilities
948 Based on pinning v14
949 */
950 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
951 if (status < 0)
952 goto error;
953 /* driver 0.9.0 */
954 switch ((sioTopJtagidLo >> 29) & 0xF) {
955 case 0:
956 state->m_deviceSpin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300957 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300958 break;
959 case 2:
960 state->m_deviceSpin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300961 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300962 break;
963 case 3:
964 state->m_deviceSpin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300965 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300966 break;
967 default:
968 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
969 status = -EINVAL;
970 printk(KERN_ERR "drxk: Spin unknown\n");
971 goto error2;
972 }
973 switch ((sioTopJtagidLo >> 12) & 0xFF) {
974 case 0x13:
975 /* typeId = DRX3913K_TYPE_ID */
976 state->m_hasLNA = false;
977 state->m_hasOOB = false;
978 state->m_hasATV = false;
979 state->m_hasAudio = false;
980 state->m_hasDVBT = true;
981 state->m_hasDVBC = true;
982 state->m_hasSAWSW = true;
983 state->m_hasGPIO2 = false;
984 state->m_hasGPIO1 = false;
985 state->m_hasIRQN = false;
986 break;
987 case 0x15:
988 /* typeId = DRX3915K_TYPE_ID */
989 state->m_hasLNA = false;
990 state->m_hasOOB = false;
991 state->m_hasATV = true;
992 state->m_hasAudio = false;
993 state->m_hasDVBT = true;
994 state->m_hasDVBC = false;
995 state->m_hasSAWSW = true;
996 state->m_hasGPIO2 = true;
997 state->m_hasGPIO1 = true;
998 state->m_hasIRQN = false;
999 break;
1000 case 0x16:
1001 /* typeId = DRX3916K_TYPE_ID */
1002 state->m_hasLNA = false;
1003 state->m_hasOOB = false;
1004 state->m_hasATV = true;
1005 state->m_hasAudio = false;
1006 state->m_hasDVBT = true;
1007 state->m_hasDVBC = false;
1008 state->m_hasSAWSW = true;
1009 state->m_hasGPIO2 = true;
1010 state->m_hasGPIO1 = true;
1011 state->m_hasIRQN = false;
1012 break;
1013 case 0x18:
1014 /* typeId = DRX3918K_TYPE_ID */
1015 state->m_hasLNA = false;
1016 state->m_hasOOB = false;
1017 state->m_hasATV = true;
1018 state->m_hasAudio = true;
1019 state->m_hasDVBT = true;
1020 state->m_hasDVBC = false;
1021 state->m_hasSAWSW = true;
1022 state->m_hasGPIO2 = true;
1023 state->m_hasGPIO1 = true;
1024 state->m_hasIRQN = false;
1025 break;
1026 case 0x21:
1027 /* typeId = DRX3921K_TYPE_ID */
1028 state->m_hasLNA = false;
1029 state->m_hasOOB = false;
1030 state->m_hasATV = true;
1031 state->m_hasAudio = true;
1032 state->m_hasDVBT = true;
1033 state->m_hasDVBC = true;
1034 state->m_hasSAWSW = true;
1035 state->m_hasGPIO2 = true;
1036 state->m_hasGPIO1 = true;
1037 state->m_hasIRQN = false;
1038 break;
1039 case 0x23:
1040 /* typeId = DRX3923K_TYPE_ID */
1041 state->m_hasLNA = false;
1042 state->m_hasOOB = false;
1043 state->m_hasATV = true;
1044 state->m_hasAudio = true;
1045 state->m_hasDVBT = true;
1046 state->m_hasDVBC = true;
1047 state->m_hasSAWSW = true;
1048 state->m_hasGPIO2 = true;
1049 state->m_hasGPIO1 = true;
1050 state->m_hasIRQN = false;
1051 break;
1052 case 0x25:
1053 /* typeId = DRX3925K_TYPE_ID */
1054 state->m_hasLNA = false;
1055 state->m_hasOOB = false;
1056 state->m_hasATV = true;
1057 state->m_hasAudio = true;
1058 state->m_hasDVBT = true;
1059 state->m_hasDVBC = true;
1060 state->m_hasSAWSW = true;
1061 state->m_hasGPIO2 = true;
1062 state->m_hasGPIO1 = true;
1063 state->m_hasIRQN = false;
1064 break;
1065 case 0x26:
1066 /* typeId = DRX3926K_TYPE_ID */
1067 state->m_hasLNA = false;
1068 state->m_hasOOB = false;
1069 state->m_hasATV = true;
1070 state->m_hasAudio = false;
1071 state->m_hasDVBT = true;
1072 state->m_hasDVBC = true;
1073 state->m_hasSAWSW = true;
1074 state->m_hasGPIO2 = true;
1075 state->m_hasGPIO1 = true;
1076 state->m_hasIRQN = false;
1077 break;
1078 default:
1079 printk(KERN_ERR "drxk: DeviceID not supported = %02x\n",
1080 ((sioTopJtagidLo >> 12) & 0xFF));
1081 status = -EINVAL;
1082 goto error2;
1083 }
1084
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -03001085 printk(KERN_INFO
1086 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
1087 ((sioTopJtagidLo >> 12) & 0xFF), spin,
1088 state->m_oscClockFreq / 1000,
1089 state->m_oscClockFreq % 1000);
1090
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001091error:
1092 if (status < 0)
1093 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1094
1095error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001096 return status;
1097}
1098
1099static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1100{
1101 int status;
1102 bool powerdown_cmd;
1103
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001104 dprintk(1, "\n");
1105
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001106 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001107 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001108 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001109 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001110 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1111 msleep(1);
1112
1113 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001114 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1115 ((state->m_HICfgCtrl) &
1116 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1117 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001118 if (powerdown_cmd == false) {
1119 /* Wait until command rdy */
1120 u32 retryCount = 0;
1121 u16 waitCmd;
1122
1123 do {
1124 msleep(1);
1125 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001126 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1127 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001128 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1129 && (waitCmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001130 if (status < 0)
1131 goto error;
1132 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001133 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001134error:
1135 if (status < 0)
1136 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1137
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001138 return status;
1139}
1140
1141static int HI_CfgCommand(struct drxk_state *state)
1142{
1143 int status;
1144
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001145 dprintk(1, "\n");
1146
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001147 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001148
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001149 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1150 if (status < 0)
1151 goto error;
1152 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1153 if (status < 0)
1154 goto error;
1155 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1156 if (status < 0)
1157 goto error;
1158 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1159 if (status < 0)
1160 goto error;
1161 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1162 if (status < 0)
1163 goto error;
1164 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1165 if (status < 0)
1166 goto error;
1167 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1168 if (status < 0)
1169 goto error;
1170
1171 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1172error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001173 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001174 if (status < 0)
1175 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001176 return status;
1177}
1178
1179static int InitHI(struct drxk_state *state)
1180{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001181 dprintk(1, "\n");
1182
Oliver Endrissebc7de22011-07-03 13:49:44 -03001183 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001184 state->m_HICfgTimeout = 0x96FF;
1185 /* port/bridge/power down ctrl */
1186 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001187
Oliver Endrissebc7de22011-07-03 13:49:44 -03001188 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001189}
1190
1191static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1192{
1193 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001194 u16 sioPdrMclkCfg = 0;
1195 u16 sioPdrMdxCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001196
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001197 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001198
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001199 /* stop lock indicator process */
1200 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1201 if (status < 0)
1202 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001203
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001204 /* MPEG TS pad configuration */
1205 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1206 if (status < 0)
1207 goto error;
1208
1209 if (mpegEnable == false) {
1210 /* Set MPEG TS pads to inputmode */
1211 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1212 if (status < 0)
1213 goto error;
1214 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1215 if (status < 0)
1216 goto error;
1217 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1218 if (status < 0)
1219 goto error;
1220 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1221 if (status < 0)
1222 goto error;
1223 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1224 if (status < 0)
1225 goto error;
1226 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1227 if (status < 0)
1228 goto error;
1229 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1230 if (status < 0)
1231 goto error;
1232 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1233 if (status < 0)
1234 goto error;
1235 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1236 if (status < 0)
1237 goto error;
1238 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1239 if (status < 0)
1240 goto error;
1241 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1242 if (status < 0)
1243 goto error;
1244 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1245 if (status < 0)
1246 goto error;
1247 } else {
1248 /* Enable MPEG output */
1249 sioPdrMdxCfg =
1250 ((state->m_TSDataStrength <<
1251 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1252 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1253 SIO_PDR_MCLK_CFG_DRIVE__B) |
1254 0x0003);
1255
1256 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1257 if (status < 0)
1258 goto error;
1259 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
1260 if (status < 0)
1261 goto error;
1262 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
1263 if (status < 0)
1264 goto error;
1265 if (state->m_enableParallel == true) {
1266 /* paralel -> enable MD1 to MD7 */
1267 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001268 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001269 goto error;
1270 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001271 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001272 goto error;
1273 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001274 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001275 goto error;
1276 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001277 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001278 goto error;
1279 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001280 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001281 goto error;
1282 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1283 if (status < 0)
1284 goto error;
1285 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1286 if (status < 0)
1287 goto error;
1288 } else {
1289 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1290 SIO_PDR_MD0_CFG_DRIVE__B)
1291 | 0x0003);
1292 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001293 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001294 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001295 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001296 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001297 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001298 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001299 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001300 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001301 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001302 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001303 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001304 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001305 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001306 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001307 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001308 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001309 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001310 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001311 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001312 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001313 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001314 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001315 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001316 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001317 goto error;
1318 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001319 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001320 goto error;
1321 }
1322 /* Enable MB output over MPEG pads and ctl input */
1323 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1324 if (status < 0)
1325 goto error;
1326 /* Write nomagic word to enable pdr reg write */
1327 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1328error:
1329 if (status < 0)
1330 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001331 return status;
1332}
1333
1334static int MPEGTSDisable(struct drxk_state *state)
1335{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001336 dprintk(1, "\n");
1337
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001338 return MPEGTSConfigurePins(state, false);
1339}
1340
1341static int BLChainCmd(struct drxk_state *state,
1342 u16 romOffset, u16 nrOfElements, u32 timeOut)
1343{
1344 u16 blStatus = 0;
1345 int status;
1346 unsigned long end;
1347
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001348 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001349 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001350 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1351 if (status < 0)
1352 goto error;
1353 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1354 if (status < 0)
1355 goto error;
1356 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1357 if (status < 0)
1358 goto error;
1359 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1360 if (status < 0)
1361 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001362
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001363 end = jiffies + msecs_to_jiffies(timeOut);
1364 do {
1365 msleep(1);
1366 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1367 if (status < 0)
1368 goto error;
1369 } while ((blStatus == 0x1) &&
1370 ((time_is_after_jiffies(end))));
1371
1372 if (blStatus == 0x1) {
1373 printk(KERN_ERR "drxk: SIO not ready\n");
1374 status = -EINVAL;
1375 goto error2;
1376 }
1377error:
1378 if (status < 0)
1379 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1380error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001381 mutex_unlock(&state->mutex);
1382 return status;
1383}
1384
1385
1386static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001387 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001388{
1389 const u8 *pSrc = pMCImage;
1390 u16 Flags;
1391 u16 Drain;
1392 u32 Address;
1393 u16 nBlocks;
1394 u16 BlockSize;
1395 u16 BlockCRC;
1396 u32 offset = 0;
1397 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001398 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001399
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001400 dprintk(1, "\n");
1401
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001402 /* down the drain (we don care about MAGIC_WORD) */
1403 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001404 pSrc += sizeof(u16);
1405 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001406 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001407 pSrc += sizeof(u16);
1408 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001409
1410 for (i = 0; i < nBlocks; i += 1) {
1411 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001412 (pSrc[2] << 8) | pSrc[3];
1413 pSrc += sizeof(u32);
1414 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001415
1416 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001417 pSrc += sizeof(u16);
1418 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001419
1420 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001421 pSrc += sizeof(u16);
1422 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001423
1424 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001425 pSrc += sizeof(u16);
1426 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001427
1428 if (offset + BlockSize > Length) {
1429 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1430 return -EINVAL;
1431 }
1432
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001433 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001434 if (status < 0) {
1435 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001436 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001437 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001438 pSrc += BlockSize;
1439 offset += BlockSize;
1440 }
1441 return status;
1442}
1443
1444static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1445{
1446 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001447 u16 data = 0;
1448 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001449 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1450 unsigned long end;
1451
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001452 dprintk(1, "\n");
1453
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001454 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001455 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001456 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1457 }
1458
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001459 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1460 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001461 /* tokenring already has correct status */
1462 return status;
1463 }
1464 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001465 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001466
Oliver Endrissebc7de22011-07-03 13:49:44 -03001467 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001468 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001469 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001470 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001471 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001472 msleep(1);
1473 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001474 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001475 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001476 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001477 }
1478 return status;
1479}
1480
1481static int MPEGTSStop(struct drxk_state *state)
1482{
1483 int status = 0;
1484 u16 fecOcSncMode = 0;
1485 u16 fecOcIprMode = 0;
1486
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001487 dprintk(1, "\n");
1488
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001489 /* Gracefull shutdown (byte boundaries) */
1490 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1491 if (status < 0)
1492 goto error;
1493 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1494 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1495 if (status < 0)
1496 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001497
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001498 /* Suppress MCLK during absence of data */
1499 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1500 if (status < 0)
1501 goto error;
1502 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1503 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1504
1505error:
1506 if (status < 0)
1507 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1508
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001509 return status;
1510}
1511
1512static int scu_command(struct drxk_state *state,
1513 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001514 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001515{
1516#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1517#error DRXK register mapping no longer compatible with this routine!
1518#endif
1519 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001520 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001521 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001522 u8 buffer[34];
1523 int cnt = 0, ii;
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];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001570
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001571 /* check a few fixed error codes */
1572 if (err == SCU_RESULT_UNKSTD) {
1573 printk(KERN_ERR "drxk: SCU_RESULT_UNKSTD\n");
1574 status = -EINVAL;
1575 goto error2;
1576 } else if (err == SCU_RESULT_UNKCMD) {
1577 printk(KERN_ERR "drxk: SCU_RESULT_UNKCMD\n");
1578 status = -EINVAL;
1579 goto error2;
1580 } else if (err < 0) {
1581 /*
1582 * here it is assumed that a nagative result means
1583 * error, and positive no error
1584 */
1585 printk(KERN_ERR "drxk: %s ERROR: %d\n", __func__, err);
1586 status = -EINVAL;
1587 goto error2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001588 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001589 }
1590
1591error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001592 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001593 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001594
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001595error2:
1596 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001597 return status;
1598}
1599
1600static int SetIqmAf(struct drxk_state *state, bool active)
1601{
1602 u16 data = 0;
1603 int status;
1604
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001605 dprintk(1, "\n");
1606
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001607 /* Configure IQM */
1608 status = read16(state, IQM_AF_STDBY__A, &data);
1609 if (status < 0)
1610 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001611
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001612 if (!active) {
1613 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1614 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1615 | IQM_AF_STDBY_STDBY_PD_STANDBY
1616 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1617 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1618 } else {
1619 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1620 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1621 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1622 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1623 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1624 );
1625 }
1626 status = write16(state, IQM_AF_STDBY__A, data);
1627
1628error:
1629 if (status < 0)
1630 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001631 return status;
1632}
1633
Oliver Endrissebc7de22011-07-03 13:49:44 -03001634static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001635{
1636 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001637 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001638
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001639 dprintk(1, "\n");
1640
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001641 /* Check arguments */
1642 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001643 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001644
1645 switch (*mode) {
1646 case DRX_POWER_UP:
1647 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1648 break;
1649 case DRXK_POWER_DOWN_OFDM:
1650 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1651 break;
1652 case DRXK_POWER_DOWN_CORE:
1653 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1654 break;
1655 case DRXK_POWER_DOWN_PLL:
1656 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1657 break;
1658 case DRX_POWER_DOWN:
1659 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1660 break;
1661 default:
1662 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001663 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001664 break;
1665 }
1666
1667 /* If already in requested power mode, do nothing */
1668 if (state->m_currentPowerMode == *mode)
1669 return 0;
1670
1671 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001672 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001673 status = PowerUpDevice(state);
1674 if (status < 0)
1675 goto error;
1676 status = DVBTEnableOFDMTokenRing(state, true);
1677 if (status < 0)
1678 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001679 }
1680
1681 if (*mode == DRX_POWER_UP) {
1682 /* Restore analog & pin configuartion */
1683 } else {
1684 /* Power down to requested mode */
1685 /* Backup some register settings */
1686 /* Set pins with possible pull-ups connected
1687 to them in input mode */
1688 /* Analog power down */
1689 /* ADC power down */
1690 /* Power down device */
1691 /* stop all comm_exec */
1692 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001693 switch (state->m_OperationMode) {
1694 case OM_DVBT:
1695 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001696 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001697 goto error;
1698 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001699 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001700 goto error;
1701 break;
1702 case OM_QAM_ITU_A:
1703 case OM_QAM_ITU_C:
1704 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001705 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001706 goto error;
1707 status = PowerDownQAM(state);
1708 if (status < 0)
1709 goto error;
1710 break;
1711 default:
1712 break;
1713 }
1714 status = DVBTEnableOFDMTokenRing(state, false);
1715 if (status < 0)
1716 goto error;
1717 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1718 if (status < 0)
1719 goto error;
1720 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1721 if (status < 0)
1722 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001723
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001724 if (*mode != DRXK_POWER_DOWN_OFDM) {
1725 state->m_HICfgCtrl |=
1726 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1727 status = HI_CfgCommand(state);
1728 if (status < 0)
1729 goto error;
1730 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001731 }
1732 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001733
1734error:
1735 if (status < 0)
1736 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1737
Oliver Endrissebc7de22011-07-03 13:49:44 -03001738 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001739}
1740
1741static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1742{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001743 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001744 u16 cmdResult = 0;
1745 u16 data = 0;
1746 int status;
1747
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001748 dprintk(1, "\n");
1749
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001750 status = read16(state, SCU_COMM_EXEC__A, &data);
1751 if (status < 0)
1752 goto error;
1753 if (data == SCU_COMM_EXEC_ACTIVE) {
1754 /* Send OFDM stop command */
1755 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001756 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001757 goto error;
1758 /* Send OFDM reset command */
1759 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1760 if (status < 0)
1761 goto error;
1762 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001763
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001764 /* Reset datapath for OFDM, processors first */
1765 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1766 if (status < 0)
1767 goto error;
1768 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1769 if (status < 0)
1770 goto error;
1771 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1772 if (status < 0)
1773 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001774
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001775 /* powerdown AFE */
1776 status = SetIqmAf(state, false);
1777 if (status < 0)
1778 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001779
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001780 /* powerdown to OFDM mode */
1781 if (setPowerMode) {
1782 status = CtrlPowerMode(state, &powerMode);
1783 if (status < 0)
1784 goto error;
1785 }
1786error:
1787 if (status < 0)
1788 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001789 return status;
1790}
1791
Oliver Endrissebc7de22011-07-03 13:49:44 -03001792static int SetOperationMode(struct drxk_state *state,
1793 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001794{
1795 int status = 0;
1796
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001797 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001798 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001799 Stop and power down previous standard
1800 TODO investigate total power down instead of partial
1801 power down depending on "previous" standard.
1802 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001803
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001804 /* disable HW lock indicator */
1805 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1806 if (status < 0)
1807 goto error;
1808
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001809 /* Device is already at the required mode */
1810 if (state->m_OperationMode == oMode)
1811 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001812
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001813 switch (state->m_OperationMode) {
1814 /* OM_NONE was added for start up */
1815 case OM_NONE:
1816 break;
1817 case OM_DVBT:
1818 status = MPEGTSStop(state);
1819 if (status < 0)
1820 goto error;
1821 status = PowerDownDVBT(state, true);
1822 if (status < 0)
1823 goto error;
1824 state->m_OperationMode = OM_NONE;
1825 break;
1826 case OM_QAM_ITU_A: /* fallthrough */
1827 case OM_QAM_ITU_C:
1828 status = MPEGTSStop(state);
1829 if (status < 0)
1830 goto error;
1831 status = PowerDownQAM(state);
1832 if (status < 0)
1833 goto error;
1834 state->m_OperationMode = OM_NONE;
1835 break;
1836 case OM_QAM_ITU_B:
1837 default:
1838 status = -EINVAL;
1839 goto error;
1840 }
1841
1842 /*
1843 Power up new standard
1844 */
1845 switch (oMode) {
1846 case OM_DVBT:
1847 state->m_OperationMode = oMode;
1848 status = SetDVBTStandard(state, oMode);
1849 if (status < 0)
1850 goto error;
1851 break;
1852 case OM_QAM_ITU_A: /* fallthrough */
1853 case OM_QAM_ITU_C:
1854 state->m_OperationMode = oMode;
1855 status = SetQAMStandard(state, oMode);
1856 if (status < 0)
1857 goto error;
1858 break;
1859 case OM_QAM_ITU_B:
1860 default:
1861 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001862 }
1863error:
1864 if (status < 0)
1865 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1866 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001867}
1868
1869static int Start(struct drxk_state *state, s32 offsetFreq,
1870 s32 IntermediateFrequency)
1871{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001872 int status = -EINVAL;
1873
1874 u16 IFreqkHz;
1875 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001876
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001877 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001878 if (state->m_DrxkState != DRXK_STOPPED &&
1879 state->m_DrxkState != DRXK_DTV_STARTED)
1880 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001881
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001882 state->m_bMirrorFreqSpect = (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001883
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001884 if (IntermediateFrequency < 0) {
1885 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1886 IntermediateFrequency = -IntermediateFrequency;
1887 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001888
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001889 switch (state->m_OperationMode) {
1890 case OM_QAM_ITU_A:
1891 case OM_QAM_ITU_C:
1892 IFreqkHz = (IntermediateFrequency / 1000);
1893 status = SetQAM(state, IFreqkHz, OffsetkHz);
1894 if (status < 0)
1895 goto error;
1896 state->m_DrxkState = DRXK_DTV_STARTED;
1897 break;
1898 case OM_DVBT:
1899 IFreqkHz = (IntermediateFrequency / 1000);
1900 status = MPEGTSStop(state);
1901 if (status < 0)
1902 goto error;
1903 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1904 if (status < 0)
1905 goto error;
1906 status = DVBTStart(state);
1907 if (status < 0)
1908 goto error;
1909 state->m_DrxkState = DRXK_DTV_STARTED;
1910 break;
1911 default:
1912 break;
1913 }
1914error:
1915 if (status < 0)
1916 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001917 return status;
1918}
1919
1920static int ShutDown(struct drxk_state *state)
1921{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001922 dprintk(1, "\n");
1923
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001924 MPEGTSStop(state);
1925 return 0;
1926}
1927
Oliver Endrissebc7de22011-07-03 13:49:44 -03001928static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1929 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001930{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001931 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001932
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001933 dprintk(1, "\n");
1934
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001935 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001936 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001937
1938 *pLockStatus = NOT_LOCKED;
1939
1940 /* define the SCU command code */
1941 switch (state->m_OperationMode) {
1942 case OM_QAM_ITU_A:
1943 case OM_QAM_ITU_B:
1944 case OM_QAM_ITU_C:
1945 status = GetQAMLockStatus(state, pLockStatus);
1946 break;
1947 case OM_DVBT:
1948 status = GetDVBTLockStatus(state, pLockStatus);
1949 break;
1950 default:
1951 break;
1952 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001953error:
1954 if (status < 0)
1955 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001956 return status;
1957}
1958
1959static int MPEGTSStart(struct drxk_state *state)
1960{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001961 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001962
1963 u16 fecOcSncMode = 0;
1964
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001965 /* Allow OC to sync again */
1966 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1967 if (status < 0)
1968 goto error;
1969 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1970 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1971 if (status < 0)
1972 goto error;
1973 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1974error:
1975 if (status < 0)
1976 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001977 return status;
1978}
1979
1980static int MPEGTSDtoInit(struct drxk_state *state)
1981{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001982 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001983
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001984 dprintk(1, "\n");
1985
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001986 /* Rate integration settings */
1987 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1988 if (status < 0)
1989 goto error;
1990 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1991 if (status < 0)
1992 goto error;
1993 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1994 if (status < 0)
1995 goto error;
1996 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1997 if (status < 0)
1998 goto error;
1999 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2000 if (status < 0)
2001 goto error;
2002 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2003 if (status < 0)
2004 goto error;
2005 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2006 if (status < 0)
2007 goto error;
2008 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2009 if (status < 0)
2010 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002011
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002012 /* Additional configuration */
2013 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2014 if (status < 0)
2015 goto error;
2016 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2017 if (status < 0)
2018 goto error;
2019 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2020error:
2021 if (status < 0)
2022 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2023
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002024 return status;
2025}
2026
Oliver Endrissebc7de22011-07-03 13:49:44 -03002027static int MPEGTSDtoSetup(struct drxk_state *state,
2028 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002029{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002030 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002031
Oliver Endrissebc7de22011-07-03 13:49:44 -03002032 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2033 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2034 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2035 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2036 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2037 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2038 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002039 u16 fecOcTmdMode = 0;
2040 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002041 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002042 bool staticCLK = false;
2043
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002044 dprintk(1, "\n");
2045
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002046 /* Check insertion of the Reed-Solomon parity bytes */
2047 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2048 if (status < 0)
2049 goto error;
2050 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2051 if (status < 0)
2052 goto error;
2053 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2054 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2055 if (state->m_insertRSByte == true) {
2056 /* enable parity symbol forward */
2057 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2058 /* MVAL disable during parity bytes */
2059 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2060 /* TS burst length to 204 */
2061 fecOcDtoBurstLen = 204;
2062 }
2063
2064 /* Check serial or parrallel output */
2065 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2066 if (state->m_enableParallel == false) {
2067 /* MPEG data output is serial -> set ipr_mode[0] */
2068 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2069 }
2070
2071 switch (oMode) {
2072 case OM_DVBT:
2073 maxBitRate = state->m_DVBTBitrate;
2074 fecOcTmdMode = 3;
2075 fecOcRcnCtlRate = 0xC00000;
2076 staticCLK = state->m_DVBTStaticCLK;
2077 break;
2078 case OM_QAM_ITU_A: /* fallthrough */
2079 case OM_QAM_ITU_C:
2080 fecOcTmdMode = 0x0004;
2081 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2082 maxBitRate = state->m_DVBCBitrate;
2083 staticCLK = state->m_DVBCStaticCLK;
2084 break;
2085 default:
2086 status = -EINVAL;
2087 } /* switch (standard) */
2088 if (status < 0)
2089 goto error;
2090
2091 /* Configure DTO's */
2092 if (staticCLK) {
2093 u32 bitRate = 0;
2094
2095 /* Rational DTO for MCLK source (static MCLK rate),
2096 Dynamic DTO for optimal grouping
2097 (avoid intra-packet gaps),
2098 DTO offset enable to sync TS burst with MSTRT */
2099 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2100 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2101 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2102 FEC_OC_FCT_MODE_VIRT_ENA__M);
2103
2104 /* Check user defined bitrate */
2105 bitRate = maxBitRate;
2106 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2107 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002108 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002109 /* Rational DTO period:
2110 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002111
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002112 Result should be floored,
2113 to make sure >= requested bitrate
2114 */
2115 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2116 * 1000) / bitRate);
2117 if (fecOcDtoPeriod <= 2)
2118 fecOcDtoPeriod = 0;
2119 else
2120 fecOcDtoPeriod -= 2;
2121 fecOcTmdIntUpdRate = 8;
2122 } else {
2123 /* (commonAttr->staticCLK == false) => dynamic mode */
2124 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2125 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2126 fecOcTmdIntUpdRate = 5;
2127 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002128
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002129 /* Write appropriate registers with requested configuration */
2130 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2131 if (status < 0)
2132 goto error;
2133 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2134 if (status < 0)
2135 goto error;
2136 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2137 if (status < 0)
2138 goto error;
2139 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2140 if (status < 0)
2141 goto error;
2142 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2143 if (status < 0)
2144 goto error;
2145 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2146 if (status < 0)
2147 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002148
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002149 /* Rate integration settings */
2150 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2151 if (status < 0)
2152 goto error;
2153 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2154 if (status < 0)
2155 goto error;
2156 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2157error:
2158 if (status < 0)
2159 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002160 return status;
2161}
2162
2163static int MPEGTSConfigurePolarity(struct drxk_state *state)
2164{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002165 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002166
2167 /* Data mask for the output data byte */
2168 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002169 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2170 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2171 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2172 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002173
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002174 dprintk(1, "\n");
2175
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002176 /* Control selective inversion of output bits */
2177 fecOcRegIprInvert &= (~(InvertDataMask));
2178 if (state->m_invertDATA == true)
2179 fecOcRegIprInvert |= InvertDataMask;
2180 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2181 if (state->m_invertERR == true)
2182 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2183 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2184 if (state->m_invertSTR == true)
2185 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2186 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2187 if (state->m_invertVAL == true)
2188 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2189 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2190 if (state->m_invertCLK == true)
2191 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002192
2193 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002194}
2195
2196#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2197
2198static int SetAgcRf(struct drxk_state *state,
2199 struct SCfgAgc *pAgcCfg, bool isDTV)
2200{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002201 int status = -EINVAL;
2202 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002203 struct SCfgAgc *pIfAgcSettings;
2204
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002205 dprintk(1, "\n");
2206
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002207 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002208 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002209
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002210 switch (pAgcCfg->ctrlMode) {
2211 case DRXK_AGC_CTRL_AUTO:
2212 /* Enable RF AGC DAC */
2213 status = read16(state, IQM_AF_STDBY__A, &data);
2214 if (status < 0)
2215 goto error;
2216 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2217 status = write16(state, IQM_AF_STDBY__A, data);
2218 if (status < 0)
2219 goto error;
2220 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2221 if (status < 0)
2222 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002223
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002224 /* Enable SCU RF AGC loop */
2225 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002226
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002227 /* Polarity */
2228 if (state->m_RfAgcPol)
2229 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2230 else
2231 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2232 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2233 if (status < 0)
2234 goto error;
2235
2236 /* Set speed (using complementary reduction value) */
2237 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2238 if (status < 0)
2239 goto error;
2240
2241 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2242 data |= (~(pAgcCfg->speed <<
2243 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2244 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2245
2246 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2247 if (status < 0)
2248 goto error;
2249
2250 if (IsDVBT(state))
2251 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2252 else if (IsQAM(state))
2253 pIfAgcSettings = &state->m_qamIfAgcCfg;
2254 else
2255 pIfAgcSettings = &state->m_atvIfAgcCfg;
2256 if (pIfAgcSettings == NULL) {
2257 status = -EINVAL;
2258 goto error;
2259 }
2260
2261 /* Set TOP, only if IF-AGC is in AUTO mode */
2262 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2263 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002264 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002265 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002266
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002267 /* Cut-Off current */
2268 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2269 if (status < 0)
2270 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002271
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002272 /* Max. output level */
2273 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2274 if (status < 0)
2275 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002276
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002277 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002278
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002279 case DRXK_AGC_CTRL_USER:
2280 /* Enable RF AGC DAC */
2281 status = read16(state, IQM_AF_STDBY__A, &data);
2282 if (status < 0)
2283 goto error;
2284 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2285 status = write16(state, IQM_AF_STDBY__A, data);
2286 if (status < 0)
2287 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002288
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002289 /* Disable SCU RF AGC loop */
2290 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2291 if (status < 0)
2292 goto error;
2293 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2294 if (state->m_RfAgcPol)
2295 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2296 else
2297 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2298 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2299 if (status < 0)
2300 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002301
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002302 /* SCU c.o.c. to 0, enabling full control range */
2303 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2304 if (status < 0)
2305 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002306
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002307 /* Write value to output pin */
2308 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2309 if (status < 0)
2310 goto error;
2311 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002312
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002313 case DRXK_AGC_CTRL_OFF:
2314 /* Disable RF AGC DAC */
2315 status = read16(state, IQM_AF_STDBY__A, &data);
2316 if (status < 0)
2317 goto error;
2318 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2319 status = write16(state, IQM_AF_STDBY__A, data);
2320 if (status < 0)
2321 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002322
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002323 /* Disable SCU RF AGC loop */
2324 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2325 if (status < 0)
2326 goto error;
2327 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2328 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2329 if (status < 0)
2330 goto error;
2331 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002332
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002333 default:
2334 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002335
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002336 }
2337error:
2338 if (status < 0)
2339 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002340 return status;
2341}
2342
2343#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2344
Oliver Endrissebc7de22011-07-03 13:49:44 -03002345static int SetAgcIf(struct drxk_state *state,
2346 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002347{
2348 u16 data = 0;
2349 int status = 0;
2350 struct SCfgAgc *pRfAgcSettings;
2351
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002352 dprintk(1, "\n");
2353
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002354 switch (pAgcCfg->ctrlMode) {
2355 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002356
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002357 /* Enable IF AGC DAC */
2358 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002359 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002360 goto error;
2361 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2362 status = write16(state, IQM_AF_STDBY__A, data);
2363 if (status < 0)
2364 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002365
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002366 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2367 if (status < 0)
2368 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002369
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002370 /* Enable SCU IF AGC loop */
2371 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2372
2373 /* Polarity */
2374 if (state->m_IfAgcPol)
2375 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2376 else
2377 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2378 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2379 if (status < 0)
2380 goto error;
2381
2382 /* Set speed (using complementary reduction value) */
2383 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2384 if (status < 0)
2385 goto error;
2386 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2387 data |= (~(pAgcCfg->speed <<
2388 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2389 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2390
2391 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2392 if (status < 0)
2393 goto error;
2394
2395 if (IsQAM(state))
2396 pRfAgcSettings = &state->m_qamRfAgcCfg;
2397 else
2398 pRfAgcSettings = &state->m_atvRfAgcCfg;
2399 if (pRfAgcSettings == NULL)
2400 return -1;
2401 /* Restore TOP */
2402 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2403 if (status < 0)
2404 goto error;
2405 break;
2406
2407 case DRXK_AGC_CTRL_USER:
2408
2409 /* Enable IF AGC DAC */
2410 status = read16(state, IQM_AF_STDBY__A, &data);
2411 if (status < 0)
2412 goto error;
2413 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2414 status = write16(state, IQM_AF_STDBY__A, data);
2415 if (status < 0)
2416 goto error;
2417
2418 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2419 if (status < 0)
2420 goto error;
2421
2422 /* Disable SCU IF AGC loop */
2423 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2424
2425 /* Polarity */
2426 if (state->m_IfAgcPol)
2427 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2428 else
2429 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2430 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2431 if (status < 0)
2432 goto error;
2433
2434 /* Write value to output pin */
2435 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2436 if (status < 0)
2437 goto error;
2438 break;
2439
2440 case DRXK_AGC_CTRL_OFF:
2441
2442 /* Disable If AGC DAC */
2443 status = read16(state, IQM_AF_STDBY__A, &data);
2444 if (status < 0)
2445 goto error;
2446 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2447 status = write16(state, IQM_AF_STDBY__A, data);
2448 if (status < 0)
2449 goto error;
2450
2451 /* Disable SCU IF AGC loop */
2452 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2453 if (status < 0)
2454 goto error;
2455 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2456 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2457 if (status < 0)
2458 goto error;
2459 break;
2460 } /* switch (agcSettingsIf->ctrlMode) */
2461
2462 /* always set the top to support
2463 configurations without if-loop */
2464 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2465error:
2466 if (status < 0)
2467 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002468 return status;
2469}
2470
2471static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2472{
2473 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002474 int status;
2475 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002476
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002477 dprintk(1, "\n");
2478
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002479 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2480 if (status < 0) {
2481 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2482 return status;
2483 }
2484
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002485 *pValue = 0;
2486
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002487 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2488 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2489 if (Level < 14000)
2490 *pValue = (14000 - Level) / 4;
2491 else
2492 *pValue = 0;
2493
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002494 return status;
2495}
2496
Oliver Endrissebc7de22011-07-03 13:49:44 -03002497static int GetQAMSignalToNoise(struct drxk_state *state,
2498 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002499{
2500 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002501 u16 qamSlErrPower = 0; /* accum. error between
2502 raw and sliced symbols */
2503 u32 qamSlSigPower = 0; /* used for MER, depends of
2504 QAM constellation */
2505 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002506
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002507 dprintk(1, "\n");
2508
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002509 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002510
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002511 /* get the register value needed for MER */
2512 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2513 if (status < 0) {
2514 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2515 return -EINVAL;
2516 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002517
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002518 switch (state->param.u.qam.modulation) {
2519 case QAM_16:
2520 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2521 break;
2522 case QAM_32:
2523 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2524 break;
2525 case QAM_64:
2526 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2527 break;
2528 case QAM_128:
2529 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2530 break;
2531 default:
2532 case QAM_256:
2533 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2534 break;
2535 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002536
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002537 if (qamSlErrPower > 0) {
2538 qamSlMer = Log10Times100(qamSlSigPower) -
2539 Log10Times100((u32) qamSlErrPower);
2540 }
2541 *pSignalToNoise = qamSlMer;
2542
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002543 return status;
2544}
2545
Oliver Endrissebc7de22011-07-03 13:49:44 -03002546static int GetDVBTSignalToNoise(struct drxk_state *state,
2547 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002548{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002549 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002550 u16 regData = 0;
2551 u32 EqRegTdSqrErrI = 0;
2552 u32 EqRegTdSqrErrQ = 0;
2553 u16 EqRegTdSqrErrExp = 0;
2554 u16 EqRegTdTpsPwrOfs = 0;
2555 u16 EqRegTdReqSmbCnt = 0;
2556 u32 tpsCnt = 0;
2557 u32 SqrErrIQ = 0;
2558 u32 a = 0;
2559 u32 b = 0;
2560 u32 c = 0;
2561 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002562 u16 transmissionParams = 0;
2563
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002564 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002565
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002566 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2567 if (status < 0)
2568 goto error;
2569 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2570 if (status < 0)
2571 goto error;
2572 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2573 if (status < 0)
2574 goto error;
2575 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2576 if (status < 0)
2577 goto error;
2578 /* Extend SQR_ERR_I operational range */
2579 EqRegTdSqrErrI = (u32) regData;
2580 if ((EqRegTdSqrErrExp > 11) &&
2581 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2582 EqRegTdSqrErrI += 0x00010000UL;
2583 }
2584 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2585 if (status < 0)
2586 goto error;
2587 /* Extend SQR_ERR_Q operational range */
2588 EqRegTdSqrErrQ = (u32) regData;
2589 if ((EqRegTdSqrErrExp > 11) &&
2590 (EqRegTdSqrErrQ < 0x00000FFFUL))
2591 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002592
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002593 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2594 if (status < 0)
2595 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002596
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002597 /* Check input data for MER */
2598
2599 /* MER calculation (in 0.1 dB) without math.h */
2600 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2601 iMER = 0;
2602 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2603 /* No error at all, this must be the HW reset value
2604 * Apparently no first measurement yet
2605 * Set MER to 0.0 */
2606 iMER = 0;
2607 } else {
2608 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2609 EqRegTdSqrErrExp;
2610 if ((transmissionParams &
2611 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2612 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2613 tpsCnt = 17;
2614 else
2615 tpsCnt = 68;
2616
2617 /* IMER = 100 * log10 (x)
2618 where x = (EqRegTdTpsPwrOfs^2 *
2619 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2620
2621 => IMER = a + b -c
2622 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2623 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2624 c = 100 * log10 (SqrErrIQ)
2625 */
2626
2627 /* log(x) x = 9bits * 9bits->18 bits */
2628 a = Log10Times100(EqRegTdTpsPwrOfs *
2629 EqRegTdTpsPwrOfs);
2630 /* log(x) x = 16bits * 7bits->23 bits */
2631 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2632 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2633 c = Log10Times100(SqrErrIQ);
2634
2635 iMER = a + b;
2636 /* No negative MER, clip to zero */
2637 if (iMER > c)
2638 iMER -= c;
2639 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002640 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002641 }
2642 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002643
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002644error:
2645 if (status < 0)
2646 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002647 return status;
2648}
2649
2650static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2651{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002652 dprintk(1, "\n");
2653
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002654 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002655 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002656 case OM_DVBT:
2657 return GetDVBTSignalToNoise(state, pSignalToNoise);
2658 case OM_QAM_ITU_A:
2659 case OM_QAM_ITU_C:
2660 return GetQAMSignalToNoise(state, pSignalToNoise);
2661 default:
2662 break;
2663 }
2664 return 0;
2665}
2666
2667#if 0
2668static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2669{
2670 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2671 int status = 0;
2672
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002673 dprintk(1, "\n");
2674
Oliver Endrissebc7de22011-07-03 13:49:44 -03002675 static s32 QE_SN[] = {
2676 51, /* QPSK 1/2 */
2677 69, /* QPSK 2/3 */
2678 79, /* QPSK 3/4 */
2679 89, /* QPSK 5/6 */
2680 97, /* QPSK 7/8 */
2681 108, /* 16-QAM 1/2 */
2682 131, /* 16-QAM 2/3 */
2683 146, /* 16-QAM 3/4 */
2684 156, /* 16-QAM 5/6 */
2685 160, /* 16-QAM 7/8 */
2686 165, /* 64-QAM 1/2 */
2687 187, /* 64-QAM 2/3 */
2688 202, /* 64-QAM 3/4 */
2689 216, /* 64-QAM 5/6 */
2690 225, /* 64-QAM 7/8 */
2691 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002692
2693 *pQuality = 0;
2694
2695 do {
2696 s32 SignalToNoise = 0;
2697 u16 Constellation = 0;
2698 u16 CodeRate = 0;
2699 u32 SignalToNoiseRel;
2700 u32 BERQuality;
2701
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002702 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2703 if (status < 0)
2704 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002705 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002706 if (status < 0)
2707 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002708 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2709
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002710 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002711 if (status < 0)
2712 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002713 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2714
2715 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2716 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2717 break;
2718 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002719 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002720 BERQuality = 100;
2721
Oliver Endrissebc7de22011-07-03 13:49:44 -03002722 if (SignalToNoiseRel < -70)
2723 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002724 else if (SignalToNoiseRel < 30)
2725 *pQuality = ((SignalToNoiseRel + 70) *
2726 BERQuality) / 100;
2727 else
2728 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002729 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002730 return 0;
2731};
2732
Oliver Endrissebc7de22011-07-03 13:49:44 -03002733static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002734{
2735 int status = 0;
2736 *pQuality = 0;
2737
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002738 dprintk(1, "\n");
2739
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002740 do {
2741 u32 SignalToNoise = 0;
2742 u32 BERQuality = 100;
2743 u32 SignalToNoiseRel = 0;
2744
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002745 status = GetQAMSignalToNoise(state, &SignalToNoise);
2746 if (status < 0)
2747 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002748
Oliver Endrissebc7de22011-07-03 13:49:44 -03002749 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002750 case QAM_16:
2751 SignalToNoiseRel = SignalToNoise - 200;
2752 break;
2753 case QAM_32:
2754 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002755 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002756 case QAM_64:
2757 SignalToNoiseRel = SignalToNoise - 260;
2758 break;
2759 case QAM_128:
2760 SignalToNoiseRel = SignalToNoise - 290;
2761 break;
2762 default:
2763 case QAM_256:
2764 SignalToNoiseRel = SignalToNoise - 320;
2765 break;
2766 }
2767
2768 if (SignalToNoiseRel < -70)
2769 *pQuality = 0;
2770 else if (SignalToNoiseRel < 30)
2771 *pQuality = ((SignalToNoiseRel + 70) *
2772 BERQuality) / 100;
2773 else
2774 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002775 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002776
2777 return status;
2778}
2779
2780static int GetQuality(struct drxk_state *state, s32 *pQuality)
2781{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002782 dprintk(1, "\n");
2783
Oliver Endrissebc7de22011-07-03 13:49:44 -03002784 switch (state->m_OperationMode) {
2785 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002786 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002787 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002788 return GetDVBCQuality(state, pQuality);
2789 default:
2790 break;
2791 }
2792
2793 return 0;
2794}
2795#endif
2796
2797/* Free data ram in SIO HI */
2798#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2799#define SIO_HI_RA_RAM_USR_END__A 0x420060
2800
2801#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2802#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2803#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2804#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2805
2806#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2807#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2808#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2809
2810static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2811{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002812 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002813
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002814 dprintk(1, "\n");
2815
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002816 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002817 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002818 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002819 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002820
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002821 if (state->no_i2c_bridge)
2822 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002823
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002824 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2825 if (status < 0)
2826 goto error;
2827 if (bEnableBridge) {
2828 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 -03002829 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002830 goto error;
2831 } else {
2832 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2833 if (status < 0)
2834 goto error;
2835 }
2836
2837 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2838
2839error:
2840 if (status < 0)
2841 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002842 return status;
2843}
2844
Oliver Endrissebc7de22011-07-03 13:49:44 -03002845static int SetPreSaw(struct drxk_state *state,
2846 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002847{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002848 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002849
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002850 dprintk(1, "\n");
2851
Oliver Endrissebc7de22011-07-03 13:49:44 -03002852 if ((pPreSawCfg == NULL)
2853 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002854 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002855
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002856 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002857error:
2858 if (status < 0)
2859 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002860 return status;
2861}
2862
2863static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002864 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002865{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002866 u16 blStatus = 0;
2867 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2868 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2869 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002870 unsigned long end;
2871
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002872 dprintk(1, "\n");
2873
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002874 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002875 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2876 if (status < 0)
2877 goto error;
2878 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2879 if (status < 0)
2880 goto error;
2881 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2882 if (status < 0)
2883 goto error;
2884 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2885 if (status < 0)
2886 goto error;
2887 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2888 if (status < 0)
2889 goto error;
2890 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2891 if (status < 0)
2892 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002893
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002894 end = jiffies + msecs_to_jiffies(timeOut);
2895 do {
2896 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2897 if (status < 0)
2898 goto error;
2899 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2900 if (blStatus == 0x1) {
2901 printk(KERN_ERR "drxk: SIO not ready\n");
2902 status = -EINVAL;
2903 goto error2;
2904 }
2905error:
2906 if (status < 0)
2907 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2908error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002909 mutex_unlock(&state->mutex);
2910 return status;
2911
2912}
2913
Oliver Endrissebc7de22011-07-03 13:49:44 -03002914static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002915{
2916 u16 data = 0;
2917 int status;
2918
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002919 dprintk(1, "\n");
2920
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002921 /* Start measurement */
2922 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2923 if (status < 0)
2924 goto error;
2925 status = write16(state, IQM_AF_START_LOCK__A, 1);
2926 if (status < 0)
2927 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002928
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002929 *count = 0;
2930 status = read16(state, IQM_AF_PHASE0__A, &data);
2931 if (status < 0)
2932 goto error;
2933 if (data == 127)
2934 *count = *count + 1;
2935 status = read16(state, IQM_AF_PHASE1__A, &data);
2936 if (status < 0)
2937 goto error;
2938 if (data == 127)
2939 *count = *count + 1;
2940 status = read16(state, IQM_AF_PHASE2__A, &data);
2941 if (status < 0)
2942 goto error;
2943 if (data == 127)
2944 *count = *count + 1;
2945
2946error:
2947 if (status < 0)
2948 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002949 return status;
2950}
2951
2952static int ADCSynchronization(struct drxk_state *state)
2953{
2954 u16 count = 0;
2955 int status;
2956
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002957 dprintk(1, "\n");
2958
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002959 status = ADCSyncMeasurement(state, &count);
2960 if (status < 0)
2961 goto error;
2962
2963 if (count == 1) {
2964 /* Try sampling on a diffrent edge */
2965 u16 clkNeg = 0;
2966
2967 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2968 if (status < 0)
2969 goto error;
2970 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2971 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2972 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2973 clkNeg |=
2974 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2975 } else {
2976 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2977 clkNeg |=
2978 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2979 }
2980 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2981 if (status < 0)
2982 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002983 status = ADCSyncMeasurement(state, &count);
2984 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002985 goto error;
2986 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002987
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002988 if (count < 2)
2989 status = -EINVAL;
2990error:
2991 if (status < 0)
2992 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002993 return status;
2994}
2995
2996static int SetFrequencyShifter(struct drxk_state *state,
2997 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002998 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002999{
3000 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003001 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003002 u32 fmFrequencyShift = 0;
3003 bool tunerMirror = !state->m_bMirrorFreqSpect;
3004 u32 adcFreq;
3005 bool adcFlip;
3006 int status;
3007 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003008 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003009 u32 frequencyShift;
3010 bool imageToSelect;
3011
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003012 dprintk(1, "\n");
3013
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003014 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003015 Program frequency shifter
3016 No need to account for mirroring on RF
3017 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003018 if (isDTV) {
3019 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3020 (state->m_OperationMode == OM_QAM_ITU_C) ||
3021 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003022 selectPosImage = true;
3023 else
3024 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003025 }
3026 if (tunerMirror)
3027 /* tuner doesn't mirror */
3028 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003029 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003030 else
3031 /* tuner mirrors */
3032 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003033 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003034 if (ifFreqActual > samplingFrequency / 2) {
3035 /* adc mirrors */
3036 adcFreq = samplingFrequency - ifFreqActual;
3037 adcFlip = true;
3038 } else {
3039 /* adc doesn't mirror */
3040 adcFreq = ifFreqActual;
3041 adcFlip = false;
3042 }
3043
3044 frequencyShift = adcFreq;
3045 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003046 adcFlip ^ selectPosImage;
3047 state->m_IqmFsRateOfs =
3048 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003049
3050 if (imageToSelect)
3051 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3052
3053 /* Program frequency shifter with tuner offset compensation */
3054 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003055 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3056 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003057 if (status < 0)
3058 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003059 return status;
3060}
3061
3062static int InitAGC(struct drxk_state *state, bool isDTV)
3063{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003064 u16 ingainTgt = 0;
3065 u16 ingainTgtMin = 0;
3066 u16 ingainTgtMax = 0;
3067 u16 clpCyclen = 0;
3068 u16 clpSumMin = 0;
3069 u16 clpDirTo = 0;
3070 u16 snsSumMin = 0;
3071 u16 snsSumMax = 0;
3072 u16 clpSumMax = 0;
3073 u16 snsDirTo = 0;
3074 u16 kiInnergainMin = 0;
3075 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003076 u16 ifIaccuHiTgtMin = 0;
3077 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003078 u16 data = 0;
3079 u16 fastClpCtrlDelay = 0;
3080 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003081 int status = 0;
3082
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003083 dprintk(1, "\n");
3084
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003085 /* Common settings */
3086 snsSumMax = 1023;
3087 ifIaccuHiTgtMin = 2047;
3088 clpCyclen = 500;
3089 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003090
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003091 /* AGCInit() not available for DVBT; init done in microcode */
3092 if (!IsQAM(state)) {
3093 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3094 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003095 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003096
3097 /* FIXME: Analog TV AGC require different settings */
3098
3099 /* Standard specific settings */
3100 clpSumMin = 8;
3101 clpDirTo = (u16) -9;
3102 clpCtrlMode = 0;
3103 snsSumMin = 8;
3104 snsDirTo = (u16) -9;
3105 kiInnergainMin = (u16) -1030;
3106 ifIaccuHiTgtMax = 0x2380;
3107 ifIaccuHiTgt = 0x2380;
3108 ingainTgtMin = 0x0511;
3109 ingainTgt = 0x0511;
3110 ingainTgtMax = 5119;
3111 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3112
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003113 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3114 if (status < 0)
3115 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003116
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003117 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3118 if (status < 0)
3119 goto error;
3120 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3121 if (status < 0)
3122 goto error;
3123 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3124 if (status < 0)
3125 goto error;
3126 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3127 if (status < 0)
3128 goto error;
3129 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3130 if (status < 0)
3131 goto error;
3132 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3133 if (status < 0)
3134 goto error;
3135 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3136 if (status < 0)
3137 goto error;
3138 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3139 if (status < 0)
3140 goto error;
3141 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3142 if (status < 0)
3143 goto error;
3144 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3145 if (status < 0)
3146 goto error;
3147 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3148 if (status < 0)
3149 goto error;
3150 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3151 if (status < 0)
3152 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003153
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003154 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3155 if (status < 0)
3156 goto error;
3157 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3158 if (status < 0)
3159 goto error;
3160 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3161 if (status < 0)
3162 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003163
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003164 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3165 if (status < 0)
3166 goto error;
3167 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3168 if (status < 0)
3169 goto error;
3170 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3171 if (status < 0)
3172 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003173
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003174 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3175 if (status < 0)
3176 goto error;
3177 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3178 if (status < 0)
3179 goto error;
3180 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3181 if (status < 0)
3182 goto error;
3183 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3184 if (status < 0)
3185 goto error;
3186 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3187 if (status < 0)
3188 goto error;
3189 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3190 if (status < 0)
3191 goto error;
3192 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3193 if (status < 0)
3194 goto error;
3195 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3196 if (status < 0)
3197 goto error;
3198 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3199 if (status < 0)
3200 goto error;
3201 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3202 if (status < 0)
3203 goto error;
3204 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3205 if (status < 0)
3206 goto error;
3207 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3208 if (status < 0)
3209 goto error;
3210 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3211 if (status < 0)
3212 goto error;
3213 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3214 if (status < 0)
3215 goto error;
3216 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3217 if (status < 0)
3218 goto error;
3219 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3220 if (status < 0)
3221 goto error;
3222 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3223 if (status < 0)
3224 goto error;
3225 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3226 if (status < 0)
3227 goto error;
3228 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3229 if (status < 0)
3230 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003231
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003232 /* Initialize inner-loop KI gain factors */
3233 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3234 if (status < 0)
3235 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003236
3237 data = 0x0657;
3238 data &= ~SCU_RAM_AGC_KI_RF__M;
3239 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3240 data &= ~SCU_RAM_AGC_KI_IF__M;
3241 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3242
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003243 status = write16(state, SCU_RAM_AGC_KI__A, data);
3244error:
3245 if (status < 0)
3246 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003247 return status;
3248}
3249
Oliver Endrissebc7de22011-07-03 13:49:44 -03003250static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003251{
3252 int status;
3253
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003254 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003255 if (packetErr == NULL)
3256 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3257 else
3258 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3259 if (status < 0)
3260 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003261 return status;
3262}
3263
3264static int DVBTScCommand(struct drxk_state *state,
3265 u16 cmd, u16 subcmd,
3266 u16 param0, u16 param1, u16 param2,
3267 u16 param3, u16 param4)
3268{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003269 u16 curCmd = 0;
3270 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003271 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003272 u16 scExec = 0;
3273 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003274
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003275 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003276 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003277 if (scExec != 1) {
3278 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003279 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003280 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003281 if (status < 0)
3282 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003283
3284 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003285 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003286 do {
3287 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003288 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003289 retryCnt++;
3290 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003291 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3292 goto error;
3293
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003294 /* Write sub-command */
3295 switch (cmd) {
3296 /* All commands using sub-cmd */
3297 case OFDM_SC_RA_RAM_CMD_PROC_START:
3298 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3299 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003300 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3301 if (status < 0)
3302 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003303 break;
3304 default:
3305 /* Do nothing */
3306 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003307 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003308
3309 /* Write needed parameters and the command */
3310 switch (cmd) {
3311 /* All commands using 5 parameters */
3312 /* All commands using 4 parameters */
3313 /* All commands using 3 parameters */
3314 /* All commands using 2 parameters */
3315 case OFDM_SC_RA_RAM_CMD_PROC_START:
3316 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3317 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003318 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003319 /* All commands using 1 parameters */
3320 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3321 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003322 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003323 /* All commands using 0 parameters */
3324 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3325 case OFDM_SC_RA_RAM_CMD_NULL:
3326 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003327 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003328 break;
3329 default:
3330 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003331 status = -EINVAL;
3332 }
3333 if (status < 0)
3334 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003335
3336 /* Wait until sc is ready processing command */
3337 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003338 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003339 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003340 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003341 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003342 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003343 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3344 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003345
3346 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003347 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003348 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003349 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003350 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003351 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003352 if (status < 0)
3353 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003354
3355 /* Retreive results parameters from SC */
3356 switch (cmd) {
3357 /* All commands yielding 5 results */
3358 /* All commands yielding 4 results */
3359 /* All commands yielding 3 results */
3360 /* All commands yielding 2 results */
3361 /* All commands yielding 1 result */
3362 case OFDM_SC_RA_RAM_CMD_USER_IO:
3363 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003364 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003365 /* All commands yielding 0 results */
3366 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3367 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3368 case OFDM_SC_RA_RAM_CMD_PROC_START:
3369 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3370 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3371 case OFDM_SC_RA_RAM_CMD_NULL:
3372 break;
3373 default:
3374 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003375 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003376 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003377 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003378error:
3379 if (status < 0)
3380 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003381 return status;
3382}
3383
Oliver Endrissebc7de22011-07-03 13:49:44 -03003384static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003385{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003386 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003387 int status;
3388
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003389 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003390 status = CtrlPowerMode(state, &powerMode);
3391 if (status < 0)
3392 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003393 return status;
3394}
3395
Oliver Endrissebc7de22011-07-03 13:49:44 -03003396static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003397{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003398 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003399
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003400 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003401 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003402 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003403 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003404 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003405 if (status < 0)
3406 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003407 return status;
3408}
3409
3410#define DEFAULT_FR_THRES_8K 4000
3411static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3412{
3413
3414 int status;
3415
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003416 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003417 if (*enabled == true) {
3418 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003419 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003420 DEFAULT_FR_THRES_8K);
3421 } else {
3422 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003423 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003424 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003425 if (status < 0)
3426 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003427
3428 return status;
3429}
3430
3431static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3432 struct DRXKCfgDvbtEchoThres_t *echoThres)
3433{
3434 u16 data = 0;
3435 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003436
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003437 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003438 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3439 if (status < 0)
3440 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003441
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003442 switch (echoThres->fftMode) {
3443 case DRX_FFTMODE_2K:
3444 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3445 data |= ((echoThres->threshold <<
3446 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3447 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3448 goto error;
3449 case DRX_FFTMODE_8K:
3450 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3451 data |= ((echoThres->threshold <<
3452 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3453 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3454 goto error;
3455 default:
3456 return -EINVAL;
3457 goto error;
3458 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003459
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003460 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3461error:
3462 if (status < 0)
3463 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003464 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003465}
3466
3467static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003468 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003469{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003470 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003471
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003472 dprintk(1, "\n");
3473
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003474 switch (*speed) {
3475 case DRXK_DVBT_SQI_SPEED_FAST:
3476 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3477 case DRXK_DVBT_SQI_SPEED_SLOW:
3478 break;
3479 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003480 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003481 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003482 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003483 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003484error:
3485 if (status < 0)
3486 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003487 return status;
3488}
3489
3490/*============================================================================*/
3491
3492/**
3493* \brief Activate DVBT specific presets
3494* \param demod instance of demodulator.
3495* \return DRXStatus_t.
3496*
3497* Called in DVBTSetStandard
3498*
3499*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003500static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003501{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003502 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003503 bool setincenable = false;
3504 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003505
Oliver Endrissebc7de22011-07-03 13:49:44 -03003506 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3507 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003508
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003509 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003510 status = DVBTCtrlSetIncEnable(state, &setincenable);
3511 if (status < 0)
3512 goto error;
3513 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3514 if (status < 0)
3515 goto error;
3516 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3517 if (status < 0)
3518 goto error;
3519 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3520 if (status < 0)
3521 goto error;
3522 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3523error:
3524 if (status < 0)
3525 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003526 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003527}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003528
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003529/*============================================================================*/
3530
3531/**
3532* \brief Initialize channelswitch-independent settings for DVBT.
3533* \param demod instance of demodulator.
3534* \return DRXStatus_t.
3535*
3536* For ROM code channel filter taps are loaded from the bootloader. For microcode
3537* the DVB-T taps from the drxk_filters.h are used.
3538*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003539static int SetDVBTStandard(struct drxk_state *state,
3540 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003541{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003542 u16 cmdResult = 0;
3543 u16 data = 0;
3544 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003545
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003546 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003547
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003548 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003549 /* added antenna switch */
3550 SwitchAntennaToDVBT(state);
3551 /* send OFDM reset command */
3552 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 -03003553 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003554 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003555
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003556 /* send OFDM setenv command */
3557 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3558 if (status < 0)
3559 goto error;
3560
3561 /* reset datapath for OFDM, processors first */
3562 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3563 if (status < 0)
3564 goto error;
3565 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3566 if (status < 0)
3567 goto error;
3568 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3569 if (status < 0)
3570 goto error;
3571
3572 /* IQM setup */
3573 /* synchronize on ofdstate->m_festart */
3574 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3575 if (status < 0)
3576 goto error;
3577 /* window size for clipping ADC detection */
3578 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3579 if (status < 0)
3580 goto error;
3581 /* window size for for sense pre-SAW detection */
3582 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3583 if (status < 0)
3584 goto error;
3585 /* sense threshold for sense pre-SAW detection */
3586 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3587 if (status < 0)
3588 goto error;
3589 status = SetIqmAf(state, true);
3590 if (status < 0)
3591 goto error;
3592
3593 status = write16(state, IQM_AF_AGC_RF__A, 0);
3594 if (status < 0)
3595 goto error;
3596
3597 /* Impulse noise cruncher setup */
3598 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3599 if (status < 0)
3600 goto error;
3601 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3602 if (status < 0)
3603 goto error;
3604 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3605 if (status < 0)
3606 goto error;
3607
3608 status = write16(state, IQM_RC_STRETCH__A, 16);
3609 if (status < 0)
3610 goto error;
3611 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3612 if (status < 0)
3613 goto error;
3614 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3615 if (status < 0)
3616 goto error;
3617 status = write16(state, IQM_CF_SCALE__A, 1600);
3618 if (status < 0)
3619 goto error;
3620 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3621 if (status < 0)
3622 goto error;
3623
3624 /* virtual clipping threshold for clipping ADC detection */
3625 status = write16(state, IQM_AF_CLP_TH__A, 448);
3626 if (status < 0)
3627 goto error;
3628 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3629 if (status < 0)
3630 goto error;
3631
3632 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3633 if (status < 0)
3634 goto error;
3635
3636 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3637 if (status < 0)
3638 goto error;
3639 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3640 if (status < 0)
3641 goto error;
3642 /* enable power measurement interrupt */
3643 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3644 if (status < 0)
3645 goto error;
3646 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3647 if (status < 0)
3648 goto error;
3649
3650 /* IQM will not be reset from here, sync ADC and update/init AGC */
3651 status = ADCSynchronization(state);
3652 if (status < 0)
3653 goto error;
3654 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3655 if (status < 0)
3656 goto error;
3657
3658 /* Halt SCU to enable safe non-atomic accesses */
3659 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3660 if (status < 0)
3661 goto error;
3662
3663 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3664 if (status < 0)
3665 goto error;
3666 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3667 if (status < 0)
3668 goto error;
3669
3670 /* Set Noise Estimation notch width and enable DC fix */
3671 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3672 if (status < 0)
3673 goto error;
3674 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3675 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3676 if (status < 0)
3677 goto error;
3678
3679 /* Activate SCU to enable SCU commands */
3680 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3681 if (status < 0)
3682 goto error;
3683
3684 if (!state->m_DRXK_A3_ROM_CODE) {
3685 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3686 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3687 if (status < 0)
3688 goto error;
3689 }
3690
3691 /* OFDM_SC setup */
3692#ifdef COMPILE_FOR_NONRT
3693 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3694 if (status < 0)
3695 goto error;
3696 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3697 if (status < 0)
3698 goto error;
3699#endif
3700
3701 /* FEC setup */
3702 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3703 if (status < 0)
3704 goto error;
3705
3706
3707#ifdef COMPILE_FOR_NONRT
3708 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3709 if (status < 0)
3710 goto error;
3711#else
3712 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3713 if (status < 0)
3714 goto error;
3715#endif
3716 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3717 if (status < 0)
3718 goto error;
3719
3720 /* Setup MPEG bus */
3721 status = MPEGTSDtoSetup(state, OM_DVBT);
3722 if (status < 0)
3723 goto error;
3724 /* Set DVBT Presets */
3725 status = DVBTActivatePresets(state);
3726 if (status < 0)
3727 goto error;
3728
3729error:
3730 if (status < 0)
3731 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003732 return status;
3733}
3734
3735/*============================================================================*/
3736/**
3737* \brief Start dvbt demodulating for channel.
3738* \param demod instance of demodulator.
3739* \return DRXStatus_t.
3740*/
3741static int DVBTStart(struct drxk_state *state)
3742{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003743 u16 param1;
3744 int status;
3745 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003746
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003747 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003748 /* Start correct processes to get in lock */
3749 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003750 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3751 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3752 if (status < 0)
3753 goto error;
3754 /* Start FEC OC */
3755 status = MPEGTSStart(state);
3756 if (status < 0)
3757 goto error;
3758 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3759 if (status < 0)
3760 goto error;
3761error:
3762 if (status < 0)
3763 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003764 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003765}
3766
3767
3768/*============================================================================*/
3769
3770/**
3771* \brief Set up dvbt demodulator for channel.
3772* \param demod instance of demodulator.
3773* \return DRXStatus_t.
3774* // original DVBTSetChannel()
3775*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003776static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3777 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003778{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003779 u16 cmdResult = 0;
3780 u16 transmissionParams = 0;
3781 u16 operationMode = 0;
3782 u32 iqmRcRateOfs = 0;
3783 u32 bandwidth = 0;
3784 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003785 int status;
3786
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003787 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003788
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003789 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3790 if (status < 0)
3791 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003792
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003793 /* Halt SCU to enable safe non-atomic accesses */
3794 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3795 if (status < 0)
3796 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003797
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003798 /* Stop processors */
3799 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3800 if (status < 0)
3801 goto error;
3802 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3803 if (status < 0)
3804 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003805
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003806 /* Mandatory fix, always stop CP, required to set spl offset back to
3807 hardware default (is set to 0 by ucode during pilot detection */
3808 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_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 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003813
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003814 /* mode */
3815 switch (state->param.u.ofdm.transmission_mode) {
3816 case TRANSMISSION_MODE_AUTO:
3817 default:
3818 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3819 /* fall through , try first guess DRX_FFTMODE_8K */
3820 case TRANSMISSION_MODE_8K:
3821 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
3822 goto error;
3823 case TRANSMISSION_MODE_2K:
3824 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
3825 goto error;
3826 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003827
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003828 /* guard */
3829 switch (state->param.u.ofdm.guard_interval) {
3830 default:
3831 case GUARD_INTERVAL_AUTO:
3832 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3833 /* fall through , try first guess DRX_GUARD_1DIV4 */
3834 case GUARD_INTERVAL_1_4:
3835 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
3836 goto error;
3837 case GUARD_INTERVAL_1_32:
3838 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
3839 goto error;
3840 case GUARD_INTERVAL_1_16:
3841 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
3842 goto error;
3843 case GUARD_INTERVAL_1_8:
3844 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
3845 goto error;
3846 }
3847
3848 /* hierarchy */
3849 switch (state->param.u.ofdm.hierarchy_information) {
3850 case HIERARCHY_AUTO:
3851 case HIERARCHY_NONE:
3852 default:
3853 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3854 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3855 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3856 /* break; */
3857 case HIERARCHY_1:
3858 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3859 break;
3860 case HIERARCHY_2:
3861 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3862 break;
3863 case HIERARCHY_4:
3864 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3865 break;
3866 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003867
3868
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003869 /* constellation */
3870 switch (state->param.u.ofdm.constellation) {
3871 case QAM_AUTO:
3872 default:
3873 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3874 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3875 case QAM_64:
3876 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3877 break;
3878 case QPSK:
3879 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3880 break;
3881 case QAM_16:
3882 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3883 break;
3884 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003885#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003886 /* No hierachical channels support in BDA */
3887 /* Priority (only for hierarchical channels) */
3888 switch (channel->priority) {
3889 case DRX_PRIORITY_LOW:
3890 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3891 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3892 OFDM_EC_SB_PRIOR_LO);
3893 break;
3894 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003895 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003896 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3897 OFDM_EC_SB_PRIOR_HI));
3898 break;
3899 case DRX_PRIORITY_UNKNOWN: /* fall through */
3900 default:
3901 status = -EINVAL;
3902 goto error;
3903 }
3904#else
3905 /* Set Priorty high */
3906 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3907 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3908 if (status < 0)
3909 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003910#endif
3911
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003912 /* coderate */
3913 switch (state->param.u.ofdm.code_rate_HP) {
3914 case FEC_AUTO:
3915 default:
3916 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3917 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3918 case FEC_2_3:
3919 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3920 break;
3921 case FEC_1_2:
3922 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3923 break;
3924 case FEC_3_4:
3925 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3926 break;
3927 case FEC_5_6:
3928 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3929 break;
3930 case FEC_7_8:
3931 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3932 break;
3933 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003934
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003935 /* SAW filter selection: normaly not necesarry, but if wanted
3936 the application can select a SAW filter via the driver by using UIOs */
3937 /* First determine real bandwidth (Hz) */
3938 /* Also set delay for impulse noise cruncher */
3939 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3940 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3941 functions */
3942 switch (state->param.u.ofdm.bandwidth) {
3943 case BANDWIDTH_AUTO:
3944 case BANDWIDTH_8_MHZ:
3945 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3946 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003947 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003948 goto error;
3949 /* cochannel protection for PAL 8 MHz */
3950 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3951 if (status < 0)
3952 goto error;
3953 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3954 if (status < 0)
3955 goto error;
3956 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3957 if (status < 0)
3958 goto error;
3959 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3960 if (status < 0)
3961 goto error;
3962 break;
3963 case BANDWIDTH_7_MHZ:
3964 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3965 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3966 if (status < 0)
3967 goto error;
3968 /* cochannel protection for PAL 7 MHz */
3969 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3970 if (status < 0)
3971 goto error;
3972 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3973 if (status < 0)
3974 goto error;
3975 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3976 if (status < 0)
3977 goto error;
3978 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3979 if (status < 0)
3980 goto error;
3981 break;
3982 case BANDWIDTH_6_MHZ:
3983 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3984 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3985 if (status < 0)
3986 goto error;
3987 /* cochannel protection for NTSC 6 MHz */
3988 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3989 if (status < 0)
3990 goto error;
3991 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3992 if (status < 0)
3993 goto error;
3994 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3995 if (status < 0)
3996 goto error;
3997 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3998 if (status < 0)
3999 goto error;
4000 break;
4001 default:
4002 status = -EINVAL;
4003 goto error;
4004 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004005
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004006 if (iqmRcRateOfs == 0) {
4007 /* Now compute IQM_RC_RATE_OFS
4008 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4009 =>
4010 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4011 */
4012 /* (SysFreq / BandWidth) * (2^28) */
4013 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4014 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4015 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4016 iqmRcRateOfs = Frac28a((u32)
4017 ((state->m_sysClockFreq *
4018 1000) / 3), bandwidth);
4019 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4020 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4021 iqmRcRateOfs += 0x80L;
4022 iqmRcRateOfs = iqmRcRateOfs >> 7;
4023 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4024 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4025 }
4026
4027 iqmRcRateOfs &=
4028 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4029 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4030 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4031 if (status < 0)
4032 goto error;
4033
4034 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004035
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004036#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004037 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4038 if (status < 0)
4039 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004040#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004041 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4042 if (status < 0)
4043 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004044
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004045 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004046
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004047 /* Activate SCU to enable SCU commands */
4048 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4049 if (status < 0)
4050 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004051
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004052 /* Enable SC after setting all other parameters */
4053 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4054 if (status < 0)
4055 goto error;
4056 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4057 if (status < 0)
4058 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004059
4060
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004061 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4062 if (status < 0)
4063 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004064
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004065 /* Write SC parameter registers, set all AUTO flags in operation mode */
4066 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4067 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4068 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4069 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4070 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4071 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4072 0, transmissionParams, param1, 0, 0, 0);
4073 if (status < 0)
4074 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004076 if (!state->m_DRXK_A3_ROM_CODE)
4077 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4078error:
4079 if (status < 0)
4080 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004081
4082 return status;
4083}
4084
4085
4086/*============================================================================*/
4087
4088/**
4089* \brief Retreive lock status .
4090* \param demod Pointer to demodulator instance.
4091* \param lockStat Pointer to lock status structure.
4092* \return DRXStatus_t.
4093*
4094*/
4095static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4096{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004097 int status;
4098 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4099 OFDM_SC_RA_RAM_LOCK_FEC__M);
4100 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4101 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004102
Oliver Endrissebc7de22011-07-03 13:49:44 -03004103 u16 ScRaRamLock = 0;
4104 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004105
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004106 dprintk(1, "\n");
4107
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004108 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004109 /* driver 0.9.0 */
4110 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004111 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004112 if (status < 0)
4113 goto end;
4114 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4115 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004116
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004117 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004118 if (status < 0)
4119 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004120
Oliver Endrissebc7de22011-07-03 13:49:44 -03004121 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4122 *pLockStatus = MPEG_LOCK;
4123 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4124 *pLockStatus = FEC_LOCK;
4125 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4126 *pLockStatus = DEMOD_LOCK;
4127 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4128 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004129end:
4130 if (status < 0)
4131 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004132
Oliver Endrissebc7de22011-07-03 13:49:44 -03004133 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004134}
4135
Oliver Endrissebc7de22011-07-03 13:49:44 -03004136static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004137{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004138 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004139 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004140
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004141 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004142 status = CtrlPowerMode(state, &powerMode);
4143 if (status < 0)
4144 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004145
Oliver Endrissebc7de22011-07-03 13:49:44 -03004146 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004147}
4148
4149
Oliver Endrissebc7de22011-07-03 13:49:44 -03004150/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004151static int PowerDownQAM(struct drxk_state *state)
4152{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004153 u16 data = 0;
4154 u16 cmdResult;
4155 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004156
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004157 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004158 status = read16(state, SCU_COMM_EXEC__A, &data);
4159 if (status < 0)
4160 goto error;
4161 if (data == SCU_COMM_EXEC_ACTIVE) {
4162 /*
4163 STOP demodulator
4164 QAM and HW blocks
4165 */
4166 /* stop all comstate->m_exec */
4167 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004168 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004169 goto error;
4170 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 -03004171 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004172 goto error;
4173 }
4174 /* powerdown AFE */
4175 status = SetIqmAf(state, false);
4176
4177error:
4178 if (status < 0)
4179 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004180
Oliver Endrissebc7de22011-07-03 13:49:44 -03004181 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004182}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004183
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004184/*============================================================================*/
4185
4186/**
4187* \brief Setup of the QAM Measurement intervals for signal quality
4188* \param demod instance of demod.
4189* \param constellation current constellation.
4190* \return DRXStatus_t.
4191*
4192* NOTE:
4193* Take into account that for certain settings the errorcounters can overflow.
4194* The implementation does not check this.
4195*
4196*/
4197static int SetQAMMeasurement(struct drxk_state *state,
4198 enum EDrxkConstellation constellation,
4199 u32 symbolRate)
4200{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004201 u32 fecBitsDesired = 0; /* BER accounting period */
4202 u32 fecRsPeriodTotal = 0; /* Total period */
4203 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4204 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004205 int status = 0;
4206
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004207 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004208
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004209 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004210 /* fecBitsDesired = symbolRate [kHz] *
4211 FrameLenght [ms] *
4212 (constellation + 1) *
4213 SyncLoss (== 1) *
4214 ViterbiLoss (==1)
4215 */
4216 switch (constellation) {
4217 case DRX_CONSTELLATION_QAM16:
4218 fecBitsDesired = 4 * symbolRate;
4219 break;
4220 case DRX_CONSTELLATION_QAM32:
4221 fecBitsDesired = 5 * symbolRate;
4222 break;
4223 case DRX_CONSTELLATION_QAM64:
4224 fecBitsDesired = 6 * symbolRate;
4225 break;
4226 case DRX_CONSTELLATION_QAM128:
4227 fecBitsDesired = 7 * symbolRate;
4228 break;
4229 case DRX_CONSTELLATION_QAM256:
4230 fecBitsDesired = 8 * symbolRate;
4231 break;
4232 default:
4233 status = -EINVAL;
4234 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004235 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004236 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004237
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004238 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4239 fecBitsDesired *= 500; /* meas. period [ms] */
4240
4241 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4242 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4243 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4244
4245 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4246 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4247 if (fecRsPrescale == 0) {
4248 /* Divide by zero (though impossible) */
4249 status = -EINVAL;
4250 if (status < 0)
4251 goto error;
4252 }
4253 fecRsPeriod =
4254 ((u16) fecRsPeriodTotal +
4255 (fecRsPrescale >> 1)) / fecRsPrescale;
4256
4257 /* write corresponding registers */
4258 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4259 if (status < 0)
4260 goto error;
4261 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4262 if (status < 0)
4263 goto error;
4264 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4265error:
4266 if (status < 0)
4267 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004268 return status;
4269}
4270
Oliver Endrissebc7de22011-07-03 13:49:44 -03004271static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004272{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004273 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004274
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004275 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004276 /* QAM Equalizer Setup */
4277 /* Equalizer */
4278 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4279 if (status < 0)
4280 goto error;
4281 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4282 if (status < 0)
4283 goto error;
4284 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4285 if (status < 0)
4286 goto error;
4287 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4288 if (status < 0)
4289 goto error;
4290 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4291 if (status < 0)
4292 goto error;
4293 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4294 if (status < 0)
4295 goto error;
4296 /* Decision Feedback Equalizer */
4297 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4298 if (status < 0)
4299 goto error;
4300 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4301 if (status < 0)
4302 goto error;
4303 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4304 if (status < 0)
4305 goto error;
4306 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4307 if (status < 0)
4308 goto error;
4309 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4310 if (status < 0)
4311 goto error;
4312 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4313 if (status < 0)
4314 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004315
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004316 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4317 if (status < 0)
4318 goto error;
4319 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4320 if (status < 0)
4321 goto error;
4322 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4323 if (status < 0)
4324 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004325
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004326 /* QAM Slicer Settings */
4327 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4328 if (status < 0)
4329 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004330
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004331 /* QAM Loop Controller Coeficients */
4332 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4333 if (status < 0)
4334 goto error;
4335 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4336 if (status < 0)
4337 goto error;
4338 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4339 if (status < 0)
4340 goto error;
4341 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4342 if (status < 0)
4343 goto error;
4344 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4345 if (status < 0)
4346 goto error;
4347 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4348 if (status < 0)
4349 goto error;
4350 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4351 if (status < 0)
4352 goto error;
4353 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4354 if (status < 0)
4355 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004356
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004357 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4358 if (status < 0)
4359 goto error;
4360 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4361 if (status < 0)
4362 goto error;
4363 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4364 if (status < 0)
4365 goto error;
4366 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4367 if (status < 0)
4368 goto error;
4369 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4370 if (status < 0)
4371 goto error;
4372 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4373 if (status < 0)
4374 goto error;
4375 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4376 if (status < 0)
4377 goto error;
4378 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4379 if (status < 0)
4380 goto error;
4381 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4382 if (status < 0)
4383 goto error;
4384 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4385 if (status < 0)
4386 goto error;
4387 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4388 if (status < 0)
4389 goto error;
4390 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4391 if (status < 0)
4392 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004393
4394
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004395 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004396
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004397 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4398 if (status < 0)
4399 goto error;
4400 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4401 if (status < 0)
4402 goto error;
4403 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4404 if (status < 0)
4405 goto error;
4406 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4407 if (status < 0)
4408 goto error;
4409 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4410 if (status < 0)
4411 goto error;
4412 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4413 if (status < 0)
4414 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004415
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004416 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4417 if (status < 0)
4418 goto error;
4419 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4420 if (status < 0)
4421 goto error;
4422 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4423 if (status < 0)
4424 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004425
4426
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004427 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004428
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004429 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4430 if (status < 0)
4431 goto error;
4432 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4433 if (status < 0)
4434 goto error;
4435 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4436 if (status < 0)
4437 goto error;
4438 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4439 if (status < 0)
4440 goto error;
4441 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4442 if (status < 0)
4443 goto error;
4444 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4445 if (status < 0)
4446 goto error;
4447 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4448 if (status < 0)
4449 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004450
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004451error:
4452 if (status < 0)
4453 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004454 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004455}
4456
4457/*============================================================================*/
4458
4459/**
4460* \brief QAM32 specific setup
4461* \param demod instance of demod.
4462* \return DRXStatus_t.
4463*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004464static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004465{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004466 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004467
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004468 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004469
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004470 /* QAM Equalizer Setup */
4471 /* Equalizer */
4472 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4473 if (status < 0)
4474 goto error;
4475 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4476 if (status < 0)
4477 goto error;
4478 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4479 if (status < 0)
4480 goto error;
4481 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4482 if (status < 0)
4483 goto error;
4484 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4485 if (status < 0)
4486 goto error;
4487 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4488 if (status < 0)
4489 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004490
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004491 /* Decision Feedback Equalizer */
4492 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4493 if (status < 0)
4494 goto error;
4495 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4496 if (status < 0)
4497 goto error;
4498 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4499 if (status < 0)
4500 goto error;
4501 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4502 if (status < 0)
4503 goto error;
4504 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4505 if (status < 0)
4506 goto error;
4507 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4508 if (status < 0)
4509 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004510
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004511 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4512 if (status < 0)
4513 goto error;
4514 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4515 if (status < 0)
4516 goto error;
4517 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4518 if (status < 0)
4519 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004520
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004521 /* QAM Slicer Settings */
4522
4523 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4524 if (status < 0)
4525 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004526
4527
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004528 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004529
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004530 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4531 if (status < 0)
4532 goto error;
4533 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4534 if (status < 0)
4535 goto error;
4536 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4537 if (status < 0)
4538 goto error;
4539 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4540 if (status < 0)
4541 goto error;
4542 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4543 if (status < 0)
4544 goto error;
4545 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4546 if (status < 0)
4547 goto error;
4548 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4549 if (status < 0)
4550 goto error;
4551 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4552 if (status < 0)
4553 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004554
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004555 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4556 if (status < 0)
4557 goto error;
4558 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4559 if (status < 0)
4560 goto error;
4561 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4562 if (status < 0)
4563 goto error;
4564 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4565 if (status < 0)
4566 goto error;
4567 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4568 if (status < 0)
4569 goto error;
4570 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4571 if (status < 0)
4572 goto error;
4573 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4574 if (status < 0)
4575 goto error;
4576 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4577 if (status < 0)
4578 goto error;
4579 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4580 if (status < 0)
4581 goto error;
4582 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4583 if (status < 0)
4584 goto error;
4585 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4586 if (status < 0)
4587 goto error;
4588 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4589 if (status < 0)
4590 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004591
4592
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004593 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004594
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004595 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4596 if (status < 0)
4597 goto error;
4598 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4599 if (status < 0)
4600 goto error;
4601 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4602 if (status < 0)
4603 goto error;
4604 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4605 if (status < 0)
4606 goto error;
4607 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4608 if (status < 0)
4609 goto error;
4610 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4611 if (status < 0)
4612 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004613
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004614 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4615 if (status < 0)
4616 goto error;
4617 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4618 if (status < 0)
4619 goto error;
4620 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4621 if (status < 0)
4622 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004623
4624
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004625 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004626
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004627 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4628 if (status < 0)
4629 goto error;
4630 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4631 if (status < 0)
4632 goto error;
4633 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4634 if (status < 0)
4635 goto error;
4636 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4637 if (status < 0)
4638 goto error;
4639 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4640 if (status < 0)
4641 goto error;
4642 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4643 if (status < 0)
4644 goto error;
4645 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4646error:
4647 if (status < 0)
4648 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004649 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004650}
4651
4652/*============================================================================*/
4653
4654/**
4655* \brief QAM64 specific setup
4656* \param demod instance of demod.
4657* \return DRXStatus_t.
4658*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004659static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004660{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004661 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004662
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004663 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004664 /* QAM Equalizer Setup */
4665 /* Equalizer */
4666 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4667 if (status < 0)
4668 goto error;
4669 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4670 if (status < 0)
4671 goto error;
4672 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4673 if (status < 0)
4674 goto error;
4675 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4676 if (status < 0)
4677 goto error;
4678 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4679 if (status < 0)
4680 goto error;
4681 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4682 if (status < 0)
4683 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004684
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004685 /* Decision Feedback Equalizer */
4686 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4687 if (status < 0)
4688 goto error;
4689 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4690 if (status < 0)
4691 goto error;
4692 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4693 if (status < 0)
4694 goto error;
4695 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4696 if (status < 0)
4697 goto error;
4698 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4699 if (status < 0)
4700 goto error;
4701 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4702 if (status < 0)
4703 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004704
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004705 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4706 if (status < 0)
4707 goto error;
4708 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4709 if (status < 0)
4710 goto error;
4711 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4712 if (status < 0)
4713 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004714
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004715 /* QAM Slicer Settings */
4716 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4717 if (status < 0)
4718 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004719
4720
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004721 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004722
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004723 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4724 if (status < 0)
4725 goto error;
4726 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4727 if (status < 0)
4728 goto error;
4729 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4730 if (status < 0)
4731 goto error;
4732 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4733 if (status < 0)
4734 goto error;
4735 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4736 if (status < 0)
4737 goto error;
4738 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4739 if (status < 0)
4740 goto error;
4741 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4742 if (status < 0)
4743 goto error;
4744 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4745 if (status < 0)
4746 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004747
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004748 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4749 if (status < 0)
4750 goto error;
4751 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4752 if (status < 0)
4753 goto error;
4754 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4755 if (status < 0)
4756 goto error;
4757 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4758 if (status < 0)
4759 goto error;
4760 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4761 if (status < 0)
4762 goto error;
4763 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4764 if (status < 0)
4765 goto error;
4766 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4767 if (status < 0)
4768 goto error;
4769 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4770 if (status < 0)
4771 goto error;
4772 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4773 if (status < 0)
4774 goto error;
4775 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4776 if (status < 0)
4777 goto error;
4778 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4779 if (status < 0)
4780 goto error;
4781 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4782 if (status < 0)
4783 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004784
4785
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004786 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004787
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004788 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4789 if (status < 0)
4790 goto error;
4791 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4792 if (status < 0)
4793 goto error;
4794 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4795 if (status < 0)
4796 goto error;
4797 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4798 if (status < 0)
4799 goto error;
4800 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4801 if (status < 0)
4802 goto error;
4803 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4804 if (status < 0)
4805 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004806
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004807 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4808 if (status < 0)
4809 goto error;
4810 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4811 if (status < 0)
4812 goto error;
4813 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4814 if (status < 0)
4815 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004816
4817
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004818 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004819
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004820 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4821 if (status < 0)
4822 goto error;
4823 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4824 if (status < 0)
4825 goto error;
4826 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4827 if (status < 0)
4828 goto error;
4829 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4830 if (status < 0)
4831 goto error;
4832 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4833 if (status < 0)
4834 goto error;
4835 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4836 if (status < 0)
4837 goto error;
4838 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4839error:
4840 if (status < 0)
4841 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004842
Oliver Endrissebc7de22011-07-03 13:49:44 -03004843 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004844}
4845
4846/*============================================================================*/
4847
4848/**
4849* \brief QAM128 specific setup
4850* \param demod: instance of demod.
4851* \return DRXStatus_t.
4852*/
4853static int SetQAM128(struct drxk_state *state)
4854{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004855 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004856
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004857 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004858 /* QAM Equalizer Setup */
4859 /* Equalizer */
4860 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4861 if (status < 0)
4862 goto error;
4863 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4864 if (status < 0)
4865 goto error;
4866 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4867 if (status < 0)
4868 goto error;
4869 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4870 if (status < 0)
4871 goto error;
4872 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4873 if (status < 0)
4874 goto error;
4875 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4876 if (status < 0)
4877 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004878
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004879 /* Decision Feedback Equalizer */
4880 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4881 if (status < 0)
4882 goto error;
4883 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4884 if (status < 0)
4885 goto error;
4886 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4887 if (status < 0)
4888 goto error;
4889 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4890 if (status < 0)
4891 goto error;
4892 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4893 if (status < 0)
4894 goto error;
4895 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4896 if (status < 0)
4897 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004898
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004899 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4900 if (status < 0)
4901 goto error;
4902 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4903 if (status < 0)
4904 goto error;
4905 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4906 if (status < 0)
4907 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004908
4909
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004910 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004911
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004912 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4913 if (status < 0)
4914 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004915
4916
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004917 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004919 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4920 if (status < 0)
4921 goto error;
4922 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4923 if (status < 0)
4924 goto error;
4925 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4926 if (status < 0)
4927 goto error;
4928 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4929 if (status < 0)
4930 goto error;
4931 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4932 if (status < 0)
4933 goto error;
4934 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4935 if (status < 0)
4936 goto error;
4937 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4938 if (status < 0)
4939 goto error;
4940 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4941 if (status < 0)
4942 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004943
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004944 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4945 if (status < 0)
4946 goto error;
4947 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4948 if (status < 0)
4949 goto error;
4950 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4951 if (status < 0)
4952 goto error;
4953 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4954 if (status < 0)
4955 goto error;
4956 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4957 if (status < 0)
4958 goto error;
4959 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4960 if (status < 0)
4961 goto error;
4962 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4963 if (status < 0)
4964 goto error;
4965 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4966 if (status < 0)
4967 goto error;
4968 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4969 if (status < 0)
4970 goto error;
4971 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4972 if (status < 0)
4973 goto error;
4974 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4975 if (status < 0)
4976 goto error;
4977 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4978 if (status < 0)
4979 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004980
4981
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004982 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004983
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004984 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4985 if (status < 0)
4986 goto error;
4987 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4988 if (status < 0)
4989 goto error;
4990 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4991 if (status < 0)
4992 goto error;
4993 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4994 if (status < 0)
4995 goto error;
4996 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4997 if (status < 0)
4998 goto error;
4999 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5000 if (status < 0)
5001 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005002
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005003 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5004 if (status < 0)
5005 goto error;
5006 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5007 if (status < 0)
5008 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005009
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005010 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5011 if (status < 0)
5012 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005013
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005014 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005015
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005016 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5017 if (status < 0)
5018 goto error;
5019 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5020 if (status < 0)
5021 goto error;
5022 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5023 if (status < 0)
5024 goto error;
5025 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5026 if (status < 0)
5027 goto error;
5028 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5029 if (status < 0)
5030 goto error;
5031 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5032 if (status < 0)
5033 goto error;
5034 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5035error:
5036 if (status < 0)
5037 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005038
Oliver Endrissebc7de22011-07-03 13:49:44 -03005039 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005040}
5041
5042/*============================================================================*/
5043
5044/**
5045* \brief QAM256 specific setup
5046* \param demod: instance of demod.
5047* \return DRXStatus_t.
5048*/
5049static int SetQAM256(struct drxk_state *state)
5050{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005051 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005052
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005053 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005054 /* QAM Equalizer Setup */
5055 /* Equalizer */
5056 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5057 if (status < 0)
5058 goto error;
5059 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5060 if (status < 0)
5061 goto error;
5062 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5063 if (status < 0)
5064 goto error;
5065 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5066 if (status < 0)
5067 goto error;
5068 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5069 if (status < 0)
5070 goto error;
5071 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5072 if (status < 0)
5073 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005074
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005075 /* Decision Feedback Equalizer */
5076 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5077 if (status < 0)
5078 goto error;
5079 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5080 if (status < 0)
5081 goto error;
5082 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5083 if (status < 0)
5084 goto error;
5085 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5086 if (status < 0)
5087 goto error;
5088 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5089 if (status < 0)
5090 goto error;
5091 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5092 if (status < 0)
5093 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005094
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005095 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5096 if (status < 0)
5097 goto error;
5098 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5099 if (status < 0)
5100 goto error;
5101 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5102 if (status < 0)
5103 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005104
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005105 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005106
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005107 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5108 if (status < 0)
5109 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005110
5111
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005112 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005113
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005114 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5115 if (status < 0)
5116 goto error;
5117 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5118 if (status < 0)
5119 goto error;
5120 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5121 if (status < 0)
5122 goto error;
5123 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5124 if (status < 0)
5125 goto error;
5126 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5127 if (status < 0)
5128 goto error;
5129 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5130 if (status < 0)
5131 goto error;
5132 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5133 if (status < 0)
5134 goto error;
5135 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5136 if (status < 0)
5137 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005138
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005139 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5140 if (status < 0)
5141 goto error;
5142 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5143 if (status < 0)
5144 goto error;
5145 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5146 if (status < 0)
5147 goto error;
5148 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5149 if (status < 0)
5150 goto error;
5151 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5152 if (status < 0)
5153 goto error;
5154 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5155 if (status < 0)
5156 goto error;
5157 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5158 if (status < 0)
5159 goto error;
5160 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5161 if (status < 0)
5162 goto error;
5163 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5164 if (status < 0)
5165 goto error;
5166 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5167 if (status < 0)
5168 goto error;
5169 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5170 if (status < 0)
5171 goto error;
5172 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5173 if (status < 0)
5174 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005175
5176
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005177 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005178
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005179 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5180 if (status < 0)
5181 goto error;
5182 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5183 if (status < 0)
5184 goto error;
5185 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5186 if (status < 0)
5187 goto error;
5188 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5189 if (status < 0)
5190 goto error;
5191 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5192 if (status < 0)
5193 goto error;
5194 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5195 if (status < 0)
5196 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005197
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005198 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5199 if (status < 0)
5200 goto error;
5201 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5202 if (status < 0)
5203 goto error;
5204 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5205 if (status < 0)
5206 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005207
5208
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005209 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005210
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005211 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5212 if (status < 0)
5213 goto error;
5214 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5215 if (status < 0)
5216 goto error;
5217 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5218 if (status < 0)
5219 goto error;
5220 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5221 if (status < 0)
5222 goto error;
5223 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5224 if (status < 0)
5225 goto error;
5226 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5227 if (status < 0)
5228 goto error;
5229 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5230error:
5231 if (status < 0)
5232 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005233 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005234}
5235
5236
5237/*============================================================================*/
5238/**
5239* \brief Reset QAM block.
5240* \param demod: instance of demod.
5241* \param channel: pointer to channel data.
5242* \return DRXStatus_t.
5243*/
5244static int QAMResetQAM(struct drxk_state *state)
5245{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005246 int status;
5247 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005248
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005249 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005250 /* Stop QAM comstate->m_exec */
5251 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5252 if (status < 0)
5253 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005254
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005255 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5256error:
5257 if (status < 0)
5258 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005259 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005260}
5261
5262/*============================================================================*/
5263
5264/**
5265* \brief Set QAM symbolrate.
5266* \param demod: instance of demod.
5267* \param channel: pointer to channel data.
5268* \return DRXStatus_t.
5269*/
5270static int QAMSetSymbolrate(struct drxk_state *state)
5271{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005272 u32 adcFrequency = 0;
5273 u32 symbFreq = 0;
5274 u32 iqmRcRate = 0;
5275 u16 ratesel = 0;
5276 u32 lcSymbRate = 0;
5277 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005278
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005279 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005280 /* Select & calculate correct IQM rate */
5281 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5282 ratesel = 0;
5283 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
5284 if (state->param.u.qam.symbol_rate <= 1188750)
5285 ratesel = 3;
5286 else if (state->param.u.qam.symbol_rate <= 2377500)
5287 ratesel = 2;
5288 else if (state->param.u.qam.symbol_rate <= 4755000)
5289 ratesel = 1;
5290 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5291 if (status < 0)
5292 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005293
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005294 /*
5295 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5296 */
5297 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5298 if (symbFreq == 0) {
5299 /* Divide by zero */
5300 status = -EINVAL;
5301 goto error;
5302 }
5303 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5304 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5305 (1 << 23);
5306 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5307 if (status < 0)
5308 goto error;
5309 state->m_iqmRcRate = iqmRcRate;
5310 /*
5311 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5312 */
5313 symbFreq = state->param.u.qam.symbol_rate;
5314 if (adcFrequency == 0) {
5315 /* Divide by zero */
5316 status = -EINVAL;
5317 goto error;
5318 }
5319 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5320 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5321 16);
5322 if (lcSymbRate > 511)
5323 lcSymbRate = 511;
5324 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005325
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005326error:
5327 if (status < 0)
5328 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005329 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005330}
5331
5332/*============================================================================*/
5333
5334/**
5335* \brief Get QAM lock status.
5336* \param demod: instance of demod.
5337* \param channel: pointer to channel data.
5338* \return DRXStatus_t.
5339*/
5340
5341static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5342{
5343 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005344 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005345
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005346 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005347 *pLockStatus = NOT_LOCKED;
5348 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005349 SCU_RAM_COMMAND_STANDARD_QAM |
5350 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5351 Result);
5352 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005353 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005354
5355 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005356 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005357 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005358 /* 0x4000 DEMOD LOCKED */
5359 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005360 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005361 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5362 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005363 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005364 /* 0xC000 NEVER LOCKED */
5365 /* (system will never be able to lock to the signal) */
5366 /* TODO: check this, intermediate & standard specific lock states are not
5367 taken into account here */
5368 *pLockStatus = NEVER_LOCK;
5369 }
5370 return status;
5371}
5372
5373#define QAM_MIRROR__M 0x03
5374#define QAM_MIRROR_NORMAL 0x00
5375#define QAM_MIRRORED 0x01
5376#define QAM_MIRROR_AUTO_ON 0x02
5377#define QAM_LOCKRANGE__M 0x10
5378#define QAM_LOCKRANGE_NORMAL 0x10
5379
Oliver Endrissebc7de22011-07-03 13:49:44 -03005380static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5381 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005382{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005383 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005384 u8 parameterLen;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005385 u16 setEnvParameters[5];
5386 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5387 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005388
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005389 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005390 /*
5391 STEP 1: reset demodulator
5392 resets FEC DI and FEC RS
5393 resets QAM block
5394 resets SCU variables
5395 */
5396 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005397 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005398 goto error;
5399 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5400 if (status < 0)
5401 goto error;
5402 status = QAMResetQAM(state);
5403 if (status < 0)
5404 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005405
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005406 /*
5407 STEP 2: configure demodulator
5408 -set env
5409 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5410 */
5411 status = QAMSetSymbolrate(state);
5412 if (status < 0)
5413 goto error;
5414
5415 /* Env parameters */
5416 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
5417 if (state->m_OperationMode == OM_QAM_ITU_C)
5418 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
5419 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5420 /* check for LOCKRANGE Extented */
5421 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5422 parameterLen = 4;
5423
5424 /* Set params */
5425 switch (state->param.u.qam.modulation) {
5426 case QAM_256:
5427 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5428 break;
5429 case QAM_AUTO:
5430 case QAM_64:
5431 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5432 break;
5433 case QAM_16:
5434 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5435 break;
5436 case QAM_32:
5437 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5438 break;
5439 case QAM_128:
5440 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5441 break;
5442 default:
5443 status = -EINVAL;
5444 break;
5445 }
5446 if (status < 0)
5447 goto error;
5448 setParamParameters[0] = state->m_Constellation; /* constellation */
5449 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5450
5451 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5452 if (status < 0)
5453 goto error;
5454
5455
5456 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5457 setup constellation independent registers */
5458#if 0
5459 status = SetFrequency(channel, tunerFreqOffset));
5460 if (status < 0)
5461 goto error;
5462#endif
5463 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5464 if (status < 0)
5465 goto error;
5466
5467 /* Setup BER measurement */
5468 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5469 if (status < 0)
5470 goto error;
5471
5472 /* Reset default values */
5473 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5474 if (status < 0)
5475 goto error;
5476 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5477 if (status < 0)
5478 goto error;
5479
5480 /* Reset default LC values */
5481 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5482 if (status < 0)
5483 goto error;
5484 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5485 if (status < 0)
5486 goto error;
5487 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5488 if (status < 0)
5489 goto error;
5490 status = write16(state, QAM_LC_MODE__A, 7);
5491 if (status < 0)
5492 goto error;
5493
5494 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5495 if (status < 0)
5496 goto error;
5497 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5498 if (status < 0)
5499 goto error;
5500 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5501 if (status < 0)
5502 goto error;
5503 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5504 if (status < 0)
5505 goto error;
5506 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5507 if (status < 0)
5508 goto error;
5509 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5510 if (status < 0)
5511 goto error;
5512 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5513 if (status < 0)
5514 goto error;
5515 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5516 if (status < 0)
5517 goto error;
5518 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5519 if (status < 0)
5520 goto error;
5521 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5522 if (status < 0)
5523 goto error;
5524 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5525 if (status < 0)
5526 goto error;
5527 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5528 if (status < 0)
5529 goto error;
5530 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5531 if (status < 0)
5532 goto error;
5533 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5534 if (status < 0)
5535 goto error;
5536 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5537 if (status < 0)
5538 goto error;
5539
5540 /* Mirroring, QAM-block starting point not inverted */
5541 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5542 if (status < 0)
5543 goto error;
5544
5545 /* Halt SCU to enable safe non-atomic accesses */
5546 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5547 if (status < 0)
5548 goto error;
5549
5550 /* STEP 4: constellation specific setup */
5551 switch (state->param.u.qam.modulation) {
5552 case QAM_16:
5553 status = SetQAM16(state);
5554 break;
5555 case QAM_32:
5556 status = SetQAM32(state);
5557 break;
5558 case QAM_AUTO:
5559 case QAM_64:
5560 status = SetQAM64(state);
5561 break;
5562 case QAM_128:
5563 status = SetQAM128(state);
5564 break;
5565 case QAM_256:
5566 status = SetQAM256(state);
5567 break;
5568 default:
5569 status = -EINVAL;
5570 break;
5571 }
5572 if (status < 0)
5573 goto error;
5574
5575 /* Activate SCU to enable SCU commands */
5576 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5577 if (status < 0)
5578 goto error;
5579
5580 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5581 /* extAttr->currentChannel.constellation = channel->constellation; */
5582 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5583 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5584 if (status < 0)
5585 goto error;
5586
5587 /* Start processes */
5588 status = MPEGTSStart(state);
5589 if (status < 0)
5590 goto error;
5591 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5592 if (status < 0)
5593 goto error;
5594 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5595 if (status < 0)
5596 goto error;
5597 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5598 if (status < 0)
5599 goto error;
5600
5601 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5602 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5603 if (status < 0)
5604 goto error;
5605
5606 /* update global DRXK data container */
5607/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5608
5609error:
5610 if (status < 0)
5611 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005612 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005613}
5614
Oliver Endrissebc7de22011-07-03 13:49:44 -03005615static int SetQAMStandard(struct drxk_state *state,
5616 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005617{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005618 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005619#ifdef DRXK_QAM_TAPS
5620#define DRXK_QAMA_TAPS_SELECT
5621#include "drxk_filters.h"
5622#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005623#endif
5624
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005625 dprintk(1, "\n");
5626
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005627 /* added antenna switch */
5628 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005629
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005630 /* Ensure correct power-up mode */
5631 status = PowerUpQAM(state);
5632 if (status < 0)
5633 goto error;
5634 /* Reset QAM block */
5635 status = QAMResetQAM(state);
5636 if (status < 0)
5637 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005638
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005639 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005640
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005641 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5642 if (status < 0)
5643 goto error;
5644 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5645 if (status < 0)
5646 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005647
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005648 /* Upload IQM Channel Filter settings by
5649 boot loader from ROM table */
5650 switch (oMode) {
5651 case OM_QAM_ITU_A:
5652 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5653 break;
5654 case OM_QAM_ITU_C:
5655 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 -03005656 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005657 goto error;
5658 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5659 break;
5660 default:
5661 status = -EINVAL;
5662 }
5663 if (status < 0)
5664 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005665
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005666 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5667 if (status < 0)
5668 goto error;
5669 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5670 if (status < 0)
5671 goto error;
5672 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5673 if (status < 0)
5674 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005675
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005676 status = write16(state, IQM_RC_STRETCH__A, 21);
5677 if (status < 0)
5678 goto error;
5679 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5680 if (status < 0)
5681 goto error;
5682 status = write16(state, IQM_AF_CLP_TH__A, 448);
5683 if (status < 0)
5684 goto error;
5685 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5686 if (status < 0)
5687 goto error;
5688 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5689 if (status < 0)
5690 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005691
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005692 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5693 if (status < 0)
5694 goto error;
5695 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5696 if (status < 0)
5697 goto error;
5698 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5699 if (status < 0)
5700 goto error;
5701 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5702 if (status < 0)
5703 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005704
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005705 /* IQM Impulse Noise Processing Unit */
5706 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5707 if (status < 0)
5708 goto error;
5709 status = write16(state, IQM_CF_DATATH__A, 1000);
5710 if (status < 0)
5711 goto error;
5712 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5713 if (status < 0)
5714 goto error;
5715 status = write16(state, IQM_CF_DET_LCT__A, 0);
5716 if (status < 0)
5717 goto error;
5718 status = write16(state, IQM_CF_WND_LEN__A, 1);
5719 if (status < 0)
5720 goto error;
5721 status = write16(state, IQM_CF_PKDTH__A, 1);
5722 if (status < 0)
5723 goto error;
5724 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5725 if (status < 0)
5726 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005727
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005728 /* turn on IQMAF. Must be done before setAgc**() */
5729 status = SetIqmAf(state, true);
5730 if (status < 0)
5731 goto error;
5732 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5733 if (status < 0)
5734 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005735
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005736 /* IQM will not be reset from here, sync ADC and update/init AGC */
5737 status = ADCSynchronization(state);
5738 if (status < 0)
5739 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005740
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005741 /* Set the FSM step period */
5742 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5743 if (status < 0)
5744 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005745
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005746 /* Halt SCU to enable safe non-atomic accesses */
5747 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5748 if (status < 0)
5749 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005750
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005751 /* No more resets of the IQM, current standard correctly set =>
5752 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005753
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005754 status = InitAGC(state, true);
5755 if (status < 0)
5756 goto error;
5757 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5758 if (status < 0)
5759 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005760
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005761 /* Configure AGC's */
5762 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5763 if (status < 0)
5764 goto error;
5765 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5766 if (status < 0)
5767 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005768
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005769 /* Activate SCU to enable SCU commands */
5770 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5771error:
5772 if (status < 0)
5773 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005774 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005775}
5776
5777static int WriteGPIO(struct drxk_state *state)
5778{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005779 int status;
5780 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005781
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005782 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005783 /* stop lock indicator process */
5784 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5785 if (status < 0)
5786 goto error;
5787
5788 /* Write magic word to enable pdr reg write */
5789 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5790 if (status < 0)
5791 goto error;
5792
5793 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005794 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5795 /* write to io pad configuration register - output mode */
5796 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5797 if (status < 0)
5798 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005799
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005800 /* use corresponding bit in io data output registar */
5801 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5802 if (status < 0)
5803 goto error;
5804 if ((state->m_GPIO & 0x0001) == 0)
5805 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5806 else
5807 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5808 /* write back to io data output register */
5809 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5810 if (status < 0)
5811 goto error;
5812 }
5813 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5814 /* write to io pad configuration register - output mode */
5815 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5816 if (status < 0)
5817 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005818
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005819 /* use corresponding bit in io data output registar */
5820 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5821 if (status < 0)
5822 goto error;
5823 if ((state->m_GPIO & 0x0002) == 0)
5824 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5825 else
5826 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5827 /* write back to io data output register */
5828 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5829 if (status < 0)
5830 goto error;
5831 }
5832 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5833 /* write to io pad configuration register - output mode */
5834 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5835 if (status < 0)
5836 goto error;
5837
5838 /* use corresponding bit in io data output registar */
5839 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5840 if (status < 0)
5841 goto error;
5842 if ((state->m_GPIO & 0x0004) == 0)
5843 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5844 else
5845 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5846 /* write back to io data output register */
5847 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5848 if (status < 0)
5849 goto error;
5850 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005851 }
5852 /* Write magic word to disable pdr reg write */
5853 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5854error:
5855 if (status < 0)
5856 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005857 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005858}
5859
5860static int SwitchAntennaToQAM(struct drxk_state *state)
5861{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005862 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005863 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005864
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005865 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005866
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005867 if (!state->antenna_gpio)
5868 return 0;
5869
5870 gpio_state = state->m_GPIO & state->antenna_gpio;
5871
5872 if (state->antenna_dvbt ^ gpio_state) {
5873 /* Antenna is on DVB-T mode. Switch */
5874 if (state->antenna_dvbt)
5875 state->m_GPIO &= ~state->antenna_gpio;
5876 else
5877 state->m_GPIO |= state->antenna_gpio;
5878 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005879 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005880 if (status < 0)
5881 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005882 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005883}
5884
5885static int SwitchAntennaToDVBT(struct drxk_state *state)
5886{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005887 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005888 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005889
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005890 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005891
5892 if (!state->antenna_gpio)
5893 return 0;
5894
5895 gpio_state = state->m_GPIO & state->antenna_gpio;
5896
5897 if (!(state->antenna_dvbt ^ gpio_state)) {
5898 /* Antenna is on DVB-C mode. Switch */
5899 if (state->antenna_dvbt)
5900 state->m_GPIO |= state->antenna_gpio;
5901 else
5902 state->m_GPIO &= ~state->antenna_gpio;
5903 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005904 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005905 if (status < 0)
5906 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005907 return status;
5908}
5909
5910
5911static int PowerDownDevice(struct drxk_state *state)
5912{
5913 /* Power down to requested mode */
5914 /* Backup some register settings */
5915 /* Set pins with possible pull-ups connected to them in input mode */
5916 /* Analog power down */
5917 /* ADC power down */
5918 /* Power down device */
5919 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005920
5921 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005922 if (state->m_bPDownOpenBridge) {
5923 /* Open I2C bridge before power down of DRXK */
5924 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005925 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005926 goto error;
5927 }
5928 /* driver 0.9.0 */
5929 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005930 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005931 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005932
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005933 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5934 if (status < 0)
5935 goto error;
5936 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5937 if (status < 0)
5938 goto error;
5939 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5940 status = HI_CfgCommand(state);
5941error:
5942 if (status < 0)
5943 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5944
5945 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005946}
5947
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005948static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005949{
5950 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005951 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005952
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005953 dprintk(1, "\n");
5954
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005955 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5956 if (err < 0) {
5957 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005958 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005959 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005960 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005961 return err;
5962 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005963 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005964 release_firmware(fw);
5965 return err;
5966}
5967
5968static int init_drxk(struct drxk_state *state)
5969{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005970 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005971 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005972 u16 driverVersion;
5973
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005974 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005975 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005976 status = PowerUpDevice(state);
5977 if (status < 0)
5978 goto error;
5979 status = DRXX_Open(state);
5980 if (status < 0)
5981 goto error;
5982 /* Soft reset of OFDM-, sys- and osc-clockdomain */
5983 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);
5984 if (status < 0)
5985 goto error;
5986 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5987 if (status < 0)
5988 goto error;
5989 /* TODO is this needed, if yes how much delay in worst case scenario */
5990 msleep(1);
5991 state->m_DRXK_A3_PATCH_CODE = true;
5992 status = GetDeviceCapabilities(state);
5993 if (status < 0)
5994 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005995
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005996 /* Bridge delay, uses oscilator clock */
5997 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5998 /* SDA brdige delay */
5999 state->m_HICfgBridgeDelay =
6000 (u16) ((state->m_oscClockFreq / 1000) *
6001 HI_I2C_BRIDGE_DELAY) / 1000;
6002 /* Clipping */
6003 if (state->m_HICfgBridgeDelay >
6004 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006005 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006006 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6007 }
6008 /* SCL bridge delay, same as SDA for now */
6009 state->m_HICfgBridgeDelay +=
6010 state->m_HICfgBridgeDelay <<
6011 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006012
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006013 status = InitHI(state);
6014 if (status < 0)
6015 goto error;
6016 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006017#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006018 if (!(state->m_DRXK_A1_ROM_CODE)
6019 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006020#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006021 {
6022 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6023 if (status < 0)
6024 goto error;
6025 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006026
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006027 /* disable MPEG port */
6028 status = MPEGTSDisable(state);
6029 if (status < 0)
6030 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006031
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006032 /* Stop AUD and SCU */
6033 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6034 if (status < 0)
6035 goto error;
6036 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6037 if (status < 0)
6038 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006039
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006040 /* enable token-ring bus through OFDM block for possible ucode upload */
6041 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6042 if (status < 0)
6043 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006044
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006045 /* include boot loader section */
6046 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6047 if (status < 0)
6048 goto error;
6049 status = BLChainCmd(state, 0, 6, 100);
6050 if (status < 0)
6051 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006052
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006053 if (!state->microcode_name)
6054 load_microcode(state, "drxk_a3.mc");
6055 else
6056 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006057
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006058 /* disable token-ring bus through OFDM block for possible ucode upload */
6059 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6060 if (status < 0)
6061 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006062
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006063 /* Run SCU for a little while to initialize microcode version numbers */
6064 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6065 if (status < 0)
6066 goto error;
6067 status = DRXX_Open(state);
6068 if (status < 0)
6069 goto error;
6070 /* added for test */
6071 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006072
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006073 powerMode = DRXK_POWER_DOWN_OFDM;
6074 status = CtrlPowerMode(state, &powerMode);
6075 if (status < 0)
6076 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006077
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006078 /* Stamp driver version number in SCU data RAM in BCD code
6079 Done to enable field application engineers to retreive drxdriver version
6080 via I2C from SCU RAM.
6081 Not using SCU command interface for SCU register access since no
6082 microcode may be present.
6083 */
6084 driverVersion =
6085 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6086 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6087 ((DRXK_VERSION_MAJOR % 10) << 4) +
6088 (DRXK_VERSION_MINOR % 10);
6089 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6090 if (status < 0)
6091 goto error;
6092 driverVersion =
6093 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6094 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6095 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6096 (DRXK_VERSION_PATCH % 10);
6097 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6098 if (status < 0)
6099 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006100
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006101 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6102 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6103 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006104
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006105 /* Dirty fix of default values for ROM/PATCH microcode
6106 Dirty because this fix makes it impossible to setup suitable values
6107 before calling DRX_Open. This solution requires changes to RF AGC speed
6108 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006109
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006110 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006111
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006112 /* Reset driver debug flags to 0 */
6113 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6114 if (status < 0)
6115 goto error;
6116 /* driver 0.9.0 */
6117 /* Setup FEC OC:
6118 NOTE: No more full FEC resets allowed afterwards!! */
6119 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6120 if (status < 0)
6121 goto error;
6122 /* MPEGTS functions are still the same */
6123 status = MPEGTSDtoInit(state);
6124 if (status < 0)
6125 goto error;
6126 status = MPEGTSStop(state);
6127 if (status < 0)
6128 goto error;
6129 status = MPEGTSConfigurePolarity(state);
6130 if (status < 0)
6131 goto error;
6132 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6133 if (status < 0)
6134 goto error;
6135 /* added: configure GPIO */
6136 status = WriteGPIO(state);
6137 if (status < 0)
6138 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006139
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006140 state->m_DrxkState = DRXK_STOPPED;
6141
6142 if (state->m_bPowerDown) {
6143 status = PowerDownDevice(state);
6144 if (status < 0)
6145 goto error;
6146 state->m_DrxkState = DRXK_POWERED_DOWN;
6147 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006148 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006149 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006150error:
6151 if (status < 0)
6152 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006153
6154 return 0;
6155}
6156
Oliver Endrissebc7de22011-07-03 13:49:44 -03006157static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006158{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006159 struct drxk_state *state = fe->demodulator_priv;
6160
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006161 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006162 kfree(state);
6163}
6164
Oliver Endrissebc7de22011-07-03 13:49:44 -03006165static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006166{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006167 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006168
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006169 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006170 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006171 return -EBUSY;
6172 SetOperationMode(state, OM_QAM_ITU_A);
6173 return 0;
6174}
6175
Oliver Endrissebc7de22011-07-03 13:49:44 -03006176static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006177{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006178 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006179
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006180 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006181 ShutDown(state);
6182 mutex_unlock(&state->ctlock);
6183 return 0;
6184}
6185
Oliver Endrissebc7de22011-07-03 13:49:44 -03006186static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006187{
6188 struct drxk_state *state = fe->demodulator_priv;
6189
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006190 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006191 return ConfigureI2CBridge(state, enable ? true : false);
6192}
6193
Oliver Endrissebc7de22011-07-03 13:49:44 -03006194static int drxk_set_parameters(struct dvb_frontend *fe,
6195 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006196{
6197 struct drxk_state *state = fe->demodulator_priv;
6198 u32 IF;
6199
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006200 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006201 if (fe->ops.i2c_gate_ctrl)
6202 fe->ops.i2c_gate_ctrl(fe, 1);
6203 if (fe->ops.tuner_ops.set_params)
6204 fe->ops.tuner_ops.set_params(fe, p);
6205 if (fe->ops.i2c_gate_ctrl)
6206 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006207 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006208 fe->ops.tuner_ops.get_frequency(fe, &IF);
6209 Start(state, 0, IF);
6210
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006211 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006212
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006213 return 0;
6214}
6215
Oliver Endrissebc7de22011-07-03 13:49:44 -03006216static int drxk_c_get_frontend(struct dvb_frontend *fe,
6217 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006218{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006219 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006220 return 0;
6221}
6222
6223static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6224{
6225 struct drxk_state *state = fe->demodulator_priv;
6226 u32 stat;
6227
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006228 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006229 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006230 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006231 if (stat == MPEG_LOCK)
6232 *status |= 0x1f;
6233 if (stat == FEC_LOCK)
6234 *status |= 0x0f;
6235 if (stat == DEMOD_LOCK)
6236 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006237 return 0;
6238}
6239
6240static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6241{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006242 dprintk(1, "\n");
6243
Oliver Endrissebc7de22011-07-03 13:49:44 -03006244 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006245 return 0;
6246}
6247
Oliver Endrissebc7de22011-07-03 13:49:44 -03006248static int drxk_read_signal_strength(struct dvb_frontend *fe,
6249 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006250{
6251 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006252 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006253
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006254 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006255 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006256 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006257 return 0;
6258}
6259
6260static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6261{
6262 struct drxk_state *state = fe->demodulator_priv;
6263 s32 snr2;
6264
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006265 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006266 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006267 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006268 return 0;
6269}
6270
6271static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6272{
6273 struct drxk_state *state = fe->demodulator_priv;
6274 u16 err;
6275
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006276 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006277 DVBTQAMGetAccPktErr(state, &err);
6278 *ucblocks = (u32) err;
6279 return 0;
6280}
6281
Oliver Endrissebc7de22011-07-03 13:49:44 -03006282static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6283 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006284{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006285 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006286 sets->min_delay_ms = 3000;
6287 sets->max_drift = 0;
6288 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006289 return 0;
6290}
6291
Oliver Endrissebc7de22011-07-03 13:49:44 -03006292static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006293{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006294#if 0
6295 struct drxk_state *state = fe->demodulator_priv;
6296
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006297 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006298 kfree(state);
6299#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006300}
6301
Oliver Endrissebc7de22011-07-03 13:49:44 -03006302static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006303{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006304 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006305
6306 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006307 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006308 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006309 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006310 return 0;
6311}
6312
Oliver Endrissebc7de22011-07-03 13:49:44 -03006313static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006314{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006315 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006316
6317 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006318 mutex_unlock(&state->ctlock);
6319 return 0;
6320}
6321
Oliver Endrissebc7de22011-07-03 13:49:44 -03006322static int drxk_t_get_frontend(struct dvb_frontend *fe,
6323 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006324{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006325 dprintk(1, "\n");
6326
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006327 return 0;
6328}
6329
6330static struct dvb_frontend_ops drxk_c_ops = {
6331 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006332 .name = "DRXK DVB-C",
6333 .type = FE_QAM,
6334 .frequency_stepsize = 62500,
6335 .frequency_min = 47000000,
6336 .frequency_max = 862000000,
6337 .symbol_rate_min = 870000,
6338 .symbol_rate_max = 11700000,
6339 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6340 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006341 .release = drxk_c_release,
6342 .init = drxk_c_init,
6343 .sleep = drxk_c_sleep,
6344 .i2c_gate_ctrl = drxk_gate_ctrl,
6345
6346 .set_frontend = drxk_set_parameters,
6347 .get_frontend = drxk_c_get_frontend,
6348 .get_tune_settings = drxk_c_get_tune_settings,
6349
6350 .read_status = drxk_read_status,
6351 .read_ber = drxk_read_ber,
6352 .read_signal_strength = drxk_read_signal_strength,
6353 .read_snr = drxk_read_snr,
6354 .read_ucblocks = drxk_read_ucblocks,
6355};
6356
6357static struct dvb_frontend_ops drxk_t_ops = {
6358 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006359 .name = "DRXK DVB-T",
6360 .type = FE_OFDM,
6361 .frequency_min = 47125000,
6362 .frequency_max = 865000000,
6363 .frequency_stepsize = 166667,
6364 .frequency_tolerance = 0,
6365 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6366 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6367 FE_CAN_FEC_AUTO |
6368 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6369 FE_CAN_QAM_AUTO |
6370 FE_CAN_TRANSMISSION_MODE_AUTO |
6371 FE_CAN_GUARD_INTERVAL_AUTO |
6372 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006373 .release = drxk_t_release,
6374 .init = drxk_t_init,
6375 .sleep = drxk_t_sleep,
6376 .i2c_gate_ctrl = drxk_gate_ctrl,
6377
6378 .set_frontend = drxk_set_parameters,
6379 .get_frontend = drxk_t_get_frontend,
6380
6381 .read_status = drxk_read_status,
6382 .read_ber = drxk_read_ber,
6383 .read_signal_strength = drxk_read_signal_strength,
6384 .read_snr = drxk_read_snr,
6385 .read_ucblocks = drxk_read_ucblocks,
6386};
6387
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006388struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6389 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006390 struct dvb_frontend **fe_t)
6391{
6392 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006393 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006394
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006395 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006396 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006397 if (!state)
6398 return NULL;
6399
Oliver Endrissebc7de22011-07-03 13:49:44 -03006400 state->i2c = i2c;
6401 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006402 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006403 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006404 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006405 state->antenna_gpio = config->antenna_gpio;
6406 state->antenna_dvbt = config->antenna_dvbt;
6407
6408 /* NOTE: as more UIO bits will be used, add them to the mask */
6409 state->UIO_mask = config->antenna_gpio;
6410
6411 /* Default gpio to DVB-C */
6412 if (!state->antenna_dvbt && state->antenna_gpio)
6413 state->m_GPIO |= state->antenna_gpio;
6414 else
6415 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006416
6417 mutex_init(&state->mutex);
6418 mutex_init(&state->ctlock);
6419
Oliver Endrissebc7de22011-07-03 13:49:44 -03006420 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6421 sizeof(struct dvb_frontend_ops));
6422 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6423 sizeof(struct dvb_frontend_ops));
6424 state->c_frontend.demodulator_priv = state;
6425 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006426
6427 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006428 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006429 goto error;
6430 *fe_t = &state->t_frontend;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006431
6432#ifdef CONFIG_MEDIA_ATTACH
6433 /*
6434 * HACK: As this function initializes both DVB-T and DVB-C fe symbols,
6435 * and calling it twice would create the state twice, leading into
6436 * memory leaks, the right way is to call it only once. However, dvb
6437 * release functions will call symbol_put twice. So, the solution is to
6438 * artificially increment the usage count, in order to allow the
6439 * driver to be released.
6440 */
6441 symbol_get(drxk_attach);
6442#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006443 return &state->c_frontend;
6444
6445error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006446 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006447 kfree(state);
6448 return NULL;
6449}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006450EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006451
6452MODULE_DESCRIPTION("DRX-K driver");
6453MODULE_AUTHOR("Ralph Metzler");
6454MODULE_LICENSE("GPL");